From 9fd5fa09a1aada1de346d4718b4cfd14192b7a48 Mon Sep 17 00:00:00 2001 From: Yxjiang <2237303+yxjiang@users.noreply.github.com> Date: Wed, 6 Aug 2025 04:39:49 -0700 Subject: [PATCH 1/7] Add .env configuration support to media-gen example - Add config.py for centralized environment variable management - Create env.example template for API key configuration - Add setup_env.py interactive setup script - Update requirements.txt with python-dotenv dependency - Enhance README.md with environment setup instructions - Update example_usage.py to show configuration status - Ensure .env files are properly ignored by git - Add configuration validation and status reporting --- .gitignore | 1 + examples/media-gen/README.md | 34 ++++++++ examples/media-gen/config.py | 90 +++++++++++++++++++++ examples/media-gen/env.example | 23 ++++++ examples/media-gen/example_usage.py | 7 +- examples/media-gen/requirements.txt | 1 + examples/media-gen/setup_env.py | 49 +++++++++++ examples/media-gen/tools/dummy_image_gen.py | 3 +- 8 files changed, 206 insertions(+), 2 deletions(-) create mode 100644 examples/media-gen/config.py create mode 100644 examples/media-gen/env.example create mode 100644 examples/media-gen/setup_env.py diff --git a/.gitignore b/.gitignore index 9c014f5..eab15b5 100644 --- a/.gitignore +++ b/.gitignore @@ -164,6 +164,7 @@ logs .env scripts .vscode +**/.env # Polymind learned facts and tools knowledge/facts/** diff --git a/examples/media-gen/README.md b/examples/media-gen/README.md index 55ee1ad..0b18754 100644 --- a/examples/media-gen/README.md +++ b/examples/media-gen/README.md @@ -35,6 +35,33 @@ source venv/bin/activate # On Windows: venv\Scripts\activate.bat pip install -r requirements.txt ``` +### Environment Configuration + +**Option 1: Use the setup script (recommended):** +```bash +python setup_env.py +``` + +**Option 2: Manual setup:** +1. **Copy the environment template:** + ```bash + cp env.example .env + ``` + +2. **Edit `.env` file with your API keys:** + ```bash + # Edit .env file with your actual API keys + nano .env # or use your preferred editor + ``` + +3. **Required API keys:** + - `OPENAI_API_KEY`: For DALL-E image generation + - `ANTHROPIC_API_KEY`: For Claude integration + - `STABILITY_API_KEY`: For Stable Diffusion + - `REPLICATE_API_TOKEN`: For various AI models + + **Note:** The `.env` file is automatically ignored by git to keep your keys secure. + ## File Structure ``` @@ -46,6 +73,9 @@ media-gen/ │ └── dummy_video_gen.py # Dummy video generation tool ├── tests/ # Test suite │ └── test_dummy_media_gen.py # Comprehensive tests +├── config.py # Environment configuration +├── env.example # Environment variables template +├── setup_env.py # Environment setup script ├── example_usage.py # Usage examples ├── requirements.txt # Dependencies ├── setup_env.sh # Linux/macOS setup script @@ -112,6 +142,10 @@ class MyVideoGen(VideoGenerationTool): ```python from tools import DummyImageGen, DummyVideoGen +from config import config + +# Check configuration status +config.print_status() # Initialize tools image_gen = DummyImageGen() diff --git a/examples/media-gen/config.py b/examples/media-gen/config.py new file mode 100644 index 0000000..0d8e27b --- /dev/null +++ b/examples/media-gen/config.py @@ -0,0 +1,90 @@ +""" +Configuration management for media generation tools. + +This module handles loading environment variables and providing +a centralized configuration interface for the media generation tools. +""" + +import os +from typing import Optional +from dotenv import load_dotenv + + +class MediaGenConfig: + """Configuration class for media generation tools.""" + + def __init__(self, env_file: str = ".env"): + """ + Initialize configuration. + + Args: + env_file: Path to the .env file to load + """ + # Load environment variables from .env file + load_dotenv(env_file) + + # API Keys + self.openai_api_key: Optional[str] = os.getenv("OPENAI_API_KEY") + self.openai_org_id: Optional[str] = os.getenv("OPENAI_ORG_ID") + self.anthropic_api_key: Optional[str] = os.getenv("ANTHROPIC_API_KEY") + self.stability_api_key: Optional[str] = os.getenv("STABILITY_API_KEY") + self.replicate_api_token: Optional[str] = os.getenv( + "REPLICATE_API_TOKEN" + ) + + # Configuration + self.default_image_model: str = os.getenv( + "DEFAULT_IMAGE_MODEL", "dall-e-3" + ) + self.default_video_model: str = os.getenv( + "DEFAULT_VIDEO_MODEL", "stable-video-diffusion" + ) + self.log_level: str = os.getenv("LOG_LEVEL", "INFO") + + def validate_api_keys(self) -> dict[str, bool]: + """ + Validate that required API keys are present. + + Returns: + Dictionary mapping API name to availability status + """ + return { + "openai": bool(self.openai_api_key), + "anthropic": bool(self.anthropic_api_key), + "stability": bool(self.stability_api_key), + "replicate": bool(self.replicate_api_token), + } + + def get_missing_keys(self) -> list[str]: + """ + Get list of missing API keys. + + Returns: + List of missing API key names + """ + available = self.validate_api_keys() + return [key for key, available in available.items() if not available] + + def print_status(self) -> None: + """Print configuration status.""" + print("Media Generation Configuration Status:") + print("=" * 40) + + api_status = self.validate_api_keys() + for api, available in api_status.items(): + status = "✓ Available" if available else "✗ Missing" + print(f"{api.capitalize()}: {status}") + + print(f"\nDefault Image Model: {self.default_image_model}") + print(f"Default Video Model: {self.default_video_model}") + print(f"Log Level: {self.log_level}") + + missing = self.get_missing_keys() + if missing: + print(f"\nMissing API keys: {', '.join(missing)}") + print("Please check your .env file and ensure all required keys " + "are set.") + + +# Global configuration instance +config = MediaGenConfig() \ No newline at end of file diff --git a/examples/media-gen/env.example b/examples/media-gen/env.example new file mode 100644 index 0000000..034d790 --- /dev/null +++ b/examples/media-gen/env.example @@ -0,0 +1,23 @@ +# Media Generation Tools Environment Variables +# Copy this file to .env and fill in your actual API keys + +# OpenAI API Configuration +OPENAI_API_KEY=your_openai_api_key_here +OPENAI_ORG_ID=your_openai_org_id_here # Optional + +# Anthropic API Configuration +ANTHROPIC_API_KEY=your_anthropic_api_key_here + +# Stability AI API Configuration +STABILITY_API_KEY=your_stability_api_key_here + +# Replicate API Configuration +REPLICATE_API_TOKEN=your_replicate_api_token_here + +# Other Media Generation APIs +# Add other API keys as needed for your specific tools + +# Configuration +DEFAULT_IMAGE_MODEL=dall-e-3 +DEFAULT_VIDEO_MODEL=stable-video-diffusion +LOG_LEVEL=INFO \ No newline at end of file diff --git a/examples/media-gen/example_usage.py b/examples/media-gen/example_usage.py index a1fc443..fec4ab8 100644 --- a/examples/media-gen/example_usage.py +++ b/examples/media-gen/example_usage.py @@ -2,10 +2,11 @@ Example usage of the media generation tools. This script demonstrates how to use the DummyImageGen and DummyVideoGen tools -with the new parameter specifications. +with the new parameter specifications and environment variable configuration. """ from tools import DummyImageGen, DummyVideoGen +from config import config def main(): @@ -13,6 +14,10 @@ def main(): print("Media Generation Tools Example") print("=" * 40) + # Check configuration status + print("\nConfiguration Status:") + config.print_status() + # Initialize tools image_gen = DummyImageGen() video_gen = DummyVideoGen() diff --git a/examples/media-gen/requirements.txt b/examples/media-gen/requirements.txt index f5babf8..639886c 100644 --- a/examples/media-gen/requirements.txt +++ b/examples/media-gen/requirements.txt @@ -9,6 +9,7 @@ polymind # Development dependencies pytest # For running tests +python-dotenv # For environment variable management # Additional dependencies that Polymind requires anthropic # For Claude integration diff --git a/examples/media-gen/setup_env.py b/examples/media-gen/setup_env.py new file mode 100644 index 0000000..a547cec --- /dev/null +++ b/examples/media-gen/setup_env.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python3 +""" +Setup script for media generation tools environment. + +This script helps users set up their .env file with the required API keys. +""" + +import shutil +from pathlib import Path + + +def setup_environment(): + """Set up the environment configuration.""" + print("Media Generation Tools Environment Setup") + print("=" * 40) + + # Check if .env already exists + env_file = Path(".env") + example_file = Path("env.example") + + if env_file.exists(): + print("✓ .env file already exists") + response = input("Do you want to overwrite it? (y/N): ").lower() + if response != 'y': + print("Setup cancelled.") + return + + # Copy example file to .env + if example_file.exists(): + shutil.copy(example_file, env_file) + print("✓ Created .env file from template") + else: + print("✗ env.example file not found") + return + + print("\nNext steps:") + print("1. Edit the .env file with your actual API keys") + print("2. Run 'python example_usage.py' to test the setup") + print("\nRequired API keys:") + print("- OPENAI_API_KEY: For DALL-E image generation") + print("- ANTHROPIC_API_KEY: For Claude integration") + print("- STABILITY_API_KEY: For Stable Diffusion") + print("- REPLICATE_API_TOKEN: For various AI models") + + print("\n✓ Environment setup completed!") + + +if __name__ == "__main__": + setup_environment() \ No newline at end of file diff --git a/examples/media-gen/tools/dummy_image_gen.py b/examples/media-gen/tools/dummy_image_gen.py index b370126..05f902f 100644 --- a/examples/media-gen/tools/dummy_image_gen.py +++ b/examples/media-gen/tools/dummy_image_gen.py @@ -68,7 +68,8 @@ def run(self, input: dict) -> dict: "aspect_ratio": aspect_ratio, "output_format": output_format, "seed": "12345", - "status": "generated (dummy)" + "status": "generated (dummy)", + "note": "This is a dummy implementation. Real tools would use API keys from .env" } } From bf97bcb0b36b98408b885cbb1208f35984b1a29b Mon Sep 17 00:00:00 2001 From: Yxjiang <2237303+yxjiang@users.noreply.github.com> Date: Wed, 6 Aug 2025 04:49:49 -0700 Subject: [PATCH 2/7] Simplify .env configuration - remove config.py and use python-dotenv directly - Remove config.py module (unnecessary complexity) - Use python-dotenv directly in example_usage.py - Simplify env.example to only include OpenAI and Replicate APIs - Update README.md and setup_env.py to reflect simplified approach - Keep only essential API keys: OPENAI_API_KEY and REPLICATE_API_TOKEN --- examples/media-gen/README.md | 13 +++-- examples/media-gen/config.py | 90 ----------------------------- examples/media-gen/env.example | 9 --- examples/media-gen/example_usage.py | 34 ++++++++++- examples/media-gen/setup_env.py | 2 - 5 files changed, 40 insertions(+), 108 deletions(-) delete mode 100644 examples/media-gen/config.py diff --git a/examples/media-gen/README.md b/examples/media-gen/README.md index 0b18754..ee627f1 100644 --- a/examples/media-gen/README.md +++ b/examples/media-gen/README.md @@ -56,8 +56,6 @@ python setup_env.py 3. **Required API keys:** - `OPENAI_API_KEY`: For DALL-E image generation - - `ANTHROPIC_API_KEY`: For Claude integration - - `STABILITY_API_KEY`: For Stable Diffusion - `REPLICATE_API_TOKEN`: For various AI models **Note:** The `.env` file is automatically ignored by git to keep your keys secure. @@ -73,7 +71,7 @@ media-gen/ │ └── dummy_video_gen.py # Dummy video generation tool ├── tests/ # Test suite │ └── test_dummy_media_gen.py # Comprehensive tests -├── config.py # Environment configuration + ├── env.example # Environment variables template ├── setup_env.py # Environment setup script ├── example_usage.py # Usage examples @@ -142,10 +140,15 @@ class MyVideoGen(VideoGenerationTool): ```python from tools import DummyImageGen, DummyVideoGen -from config import config +from dotenv import load_dotenv +import os + +# Load environment variables +load_dotenv() # Check configuration status -config.print_status() +print(f"OpenAI API Key: {'✓ Available' if os.getenv('OPENAI_API_KEY') else '✗ Missing'}") +print(f"Replicate API Token: {'✓ Available' if os.getenv('REPLICATE_API_TOKEN') else '✗ Missing'}") # Initialize tools image_gen = DummyImageGen() diff --git a/examples/media-gen/config.py b/examples/media-gen/config.py deleted file mode 100644 index 0d8e27b..0000000 --- a/examples/media-gen/config.py +++ /dev/null @@ -1,90 +0,0 @@ -""" -Configuration management for media generation tools. - -This module handles loading environment variables and providing -a centralized configuration interface for the media generation tools. -""" - -import os -from typing import Optional -from dotenv import load_dotenv - - -class MediaGenConfig: - """Configuration class for media generation tools.""" - - def __init__(self, env_file: str = ".env"): - """ - Initialize configuration. - - Args: - env_file: Path to the .env file to load - """ - # Load environment variables from .env file - load_dotenv(env_file) - - # API Keys - self.openai_api_key: Optional[str] = os.getenv("OPENAI_API_KEY") - self.openai_org_id: Optional[str] = os.getenv("OPENAI_ORG_ID") - self.anthropic_api_key: Optional[str] = os.getenv("ANTHROPIC_API_KEY") - self.stability_api_key: Optional[str] = os.getenv("STABILITY_API_KEY") - self.replicate_api_token: Optional[str] = os.getenv( - "REPLICATE_API_TOKEN" - ) - - # Configuration - self.default_image_model: str = os.getenv( - "DEFAULT_IMAGE_MODEL", "dall-e-3" - ) - self.default_video_model: str = os.getenv( - "DEFAULT_VIDEO_MODEL", "stable-video-diffusion" - ) - self.log_level: str = os.getenv("LOG_LEVEL", "INFO") - - def validate_api_keys(self) -> dict[str, bool]: - """ - Validate that required API keys are present. - - Returns: - Dictionary mapping API name to availability status - """ - return { - "openai": bool(self.openai_api_key), - "anthropic": bool(self.anthropic_api_key), - "stability": bool(self.stability_api_key), - "replicate": bool(self.replicate_api_token), - } - - def get_missing_keys(self) -> list[str]: - """ - Get list of missing API keys. - - Returns: - List of missing API key names - """ - available = self.validate_api_keys() - return [key for key, available in available.items() if not available] - - def print_status(self) -> None: - """Print configuration status.""" - print("Media Generation Configuration Status:") - print("=" * 40) - - api_status = self.validate_api_keys() - for api, available in api_status.items(): - status = "✓ Available" if available else "✗ Missing" - print(f"{api.capitalize()}: {status}") - - print(f"\nDefault Image Model: {self.default_image_model}") - print(f"Default Video Model: {self.default_video_model}") - print(f"Log Level: {self.log_level}") - - missing = self.get_missing_keys() - if missing: - print(f"\nMissing API keys: {', '.join(missing)}") - print("Please check your .env file and ensure all required keys " - "are set.") - - -# Global configuration instance -config = MediaGenConfig() \ No newline at end of file diff --git a/examples/media-gen/env.example b/examples/media-gen/env.example index 034d790..f067572 100644 --- a/examples/media-gen/env.example +++ b/examples/media-gen/env.example @@ -5,18 +5,9 @@ OPENAI_API_KEY=your_openai_api_key_here OPENAI_ORG_ID=your_openai_org_id_here # Optional -# Anthropic API Configuration -ANTHROPIC_API_KEY=your_anthropic_api_key_here - -# Stability AI API Configuration -STABILITY_API_KEY=your_stability_api_key_here - # Replicate API Configuration REPLICATE_API_TOKEN=your_replicate_api_token_here -# Other Media Generation APIs -# Add other API keys as needed for your specific tools - # Configuration DEFAULT_IMAGE_MODEL=dall-e-3 DEFAULT_VIDEO_MODEL=stable-video-diffusion diff --git a/examples/media-gen/example_usage.py b/examples/media-gen/example_usage.py index fec4ab8..bba5b92 100644 --- a/examples/media-gen/example_usage.py +++ b/examples/media-gen/example_usage.py @@ -5,8 +5,38 @@ with the new parameter specifications and environment variable configuration. """ +import os +from dotenv import load_dotenv from tools import DummyImageGen, DummyVideoGen -from config import config + + +def check_config_status(): + """Check and display configuration status.""" + print("Configuration Status:") + print("=" * 40) + + # Load environment variables + load_dotenv() + + # Check API keys + openai_key = os.getenv("OPENAI_API_KEY") + replicate_token = os.getenv("REPLICATE_API_TOKEN") + + print(f"OpenAI API Key: {'✓ Available' if openai_key else '✗ Missing'}") + print(f"Replicate API Token: " + f"{'✓ Available' if replicate_token else '✗ Missing'}") + + # Show configuration + default_image = os.getenv('DEFAULT_IMAGE_MODEL', 'dall-e-3') + default_video = os.getenv('DEFAULT_VIDEO_MODEL', 'stable-video-diffusion') + log_level = os.getenv('LOG_LEVEL', 'INFO') + + print(f"\nDefault Image Model: {default_image}") + print(f"Default Video Model: {default_video}") + print(f"Log Level: {log_level}") + + if not openai_key or not replicate_token: + print("\nMissing API keys. Please check your .env file.") def main(): @@ -16,7 +46,7 @@ def main(): # Check configuration status print("\nConfiguration Status:") - config.print_status() + check_config_status() # Initialize tools image_gen = DummyImageGen() diff --git a/examples/media-gen/setup_env.py b/examples/media-gen/setup_env.py index a547cec..21fba94 100644 --- a/examples/media-gen/setup_env.py +++ b/examples/media-gen/setup_env.py @@ -38,8 +38,6 @@ def setup_environment(): print("2. Run 'python example_usage.py' to test the setup") print("\nRequired API keys:") print("- OPENAI_API_KEY: For DALL-E image generation") - print("- ANTHROPIC_API_KEY: For Claude integration") - print("- STABILITY_API_KEY: For Stable Diffusion") print("- REPLICATE_API_TOKEN: For various AI models") print("\n✓ Environment setup completed!") From b7b3b123b83f73a41dc16d68ffc793aeb36a3b1a Mon Sep 17 00:00:00 2001 From: Yxjiang <2237303+yxjiang@users.noreply.github.com> Date: Wed, 6 Aug 2025 04:51:14 -0700 Subject: [PATCH 3/7] Fix import sorting issues for CI compliance --- examples/media-gen/example_usage.py | 2 ++ examples/media-gen/setup_env.py | 1 + 2 files changed, 3 insertions(+) diff --git a/examples/media-gen/example_usage.py b/examples/media-gen/example_usage.py index bba5b92..d15adee 100644 --- a/examples/media-gen/example_usage.py +++ b/examples/media-gen/example_usage.py @@ -6,7 +6,9 @@ """ import os + from dotenv import load_dotenv + from tools import DummyImageGen, DummyVideoGen diff --git a/examples/media-gen/setup_env.py b/examples/media-gen/setup_env.py index 21fba94..a83b97f 100644 --- a/examples/media-gen/setup_env.py +++ b/examples/media-gen/setup_env.py @@ -6,6 +6,7 @@ """ import shutil + from pathlib import Path From 597d8ac38b0b61fb1f12299f021f6089731d87f2 Mon Sep 17 00:00:00 2001 From: Yxjiang <2237303+yxjiang@users.noreply.github.com> Date: Wed, 6 Aug 2025 05:02:32 -0700 Subject: [PATCH 4/7] Fix import sorting issues and update isort configuration - Update pyproject.toml to exclude venv and site-packages from isort checks - Auto-fix import order in example_usage.py and setup_env.py - Ensure proper import grouping: stdlib, third-party, local imports --- examples/media-gen/example_usage.py | 1 - examples/media-gen/setup_env.py | 2 -- pyproject.toml | 6 +++++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/examples/media-gen/example_usage.py b/examples/media-gen/example_usage.py index d15adee..c5a0e14 100644 --- a/examples/media-gen/example_usage.py +++ b/examples/media-gen/example_usage.py @@ -8,7 +8,6 @@ import os from dotenv import load_dotenv - from tools import DummyImageGen, DummyVideoGen diff --git a/examples/media-gen/setup_env.py b/examples/media-gen/setup_env.py index a83b97f..2fdae48 100644 --- a/examples/media-gen/setup_env.py +++ b/examples/media-gen/setup_env.py @@ -4,9 +4,7 @@ This script helps users set up their .env file with the required API keys. """ - import shutil - from pathlib import Path diff --git a/pyproject.toml b/pyproject.toml index b31da67..b87d7aa 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -46,7 +46,11 @@ milvus = ["pymilvus"] line-length = 120 [tool.isort] -skip = ["__init__.py"] +profile = "black" +line_length = 120 +skip = ["__init__.py", "venv", "*/venv/*", "*/__pycache__/*", "*/site-packages/*"] +known_first_party = ["polymind"] +known_third_party = ["dotenv", "pathlib", "shutil"] [tool.flake8] max-line-length = 120 From 72fc0ef8cca16e484f084742c4f36555a875ac4a Mon Sep 17 00:00:00 2001 From: Yxjiang <2237303+yxjiang@users.noreply.github.com> Date: Wed, 6 Aug 2025 06:53:11 -0700 Subject: [PATCH 5/7] Fix import order in example_usage.py --- examples/media-gen/example_usage.py | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/media-gen/example_usage.py b/examples/media-gen/example_usage.py index c5a0e14..d15adee 100644 --- a/examples/media-gen/example_usage.py +++ b/examples/media-gen/example_usage.py @@ -8,6 +8,7 @@ import os from dotenv import load_dotenv + from tools import DummyImageGen, DummyVideoGen From a62f35d5d01af1e6cf270a6cc32613d65a57b762 Mon Sep 17 00:00:00 2001 From: Yxjiang <2237303+yxjiang@users.noreply.github.com> Date: Wed, 6 Aug 2025 06:59:05 -0700 Subject: [PATCH 6/7] Fix isort --- examples/media-gen/example_usage.py | 1 - tests/polymind/core_tools/test_llm_tools.py | 6 ++++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/examples/media-gen/example_usage.py b/examples/media-gen/example_usage.py index d15adee..c5a0e14 100644 --- a/examples/media-gen/example_usage.py +++ b/examples/media-gen/example_usage.py @@ -8,7 +8,6 @@ import os from dotenv import load_dotenv - from tools import DummyImageGen, DummyVideoGen diff --git a/tests/polymind/core_tools/test_llm_tools.py b/tests/polymind/core_tools/test_llm_tools.py index f22a1a7..1c7d9c2 100644 --- a/tests/polymind/core_tools/test_llm_tools.py +++ b/tests/polymind/core_tools/test_llm_tools.py @@ -11,8 +11,10 @@ import pytest from polymind.core.message import Message -from polymind.core_tools.llm_tool import (OpenAIChatTool, - OpenAICodeGenerationTool) +from polymind.core_tools.llm_tool import ( + OpenAIChatTool, + OpenAICodeGenerationTool, +) class TestOpenAIChatTool: From 1cc72f3921342a4c23b2fe231a8053810725d943 Mon Sep 17 00:00:00 2001 From: Yxjiang <2237303+yxjiang@users.noreply.github.com> Date: Wed, 6 Aug 2025 07:01:01 -0700 Subject: [PATCH 7/7] Fix isort --- tests/polymind/core_tools/test_llm_tools.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/polymind/core_tools/test_llm_tools.py b/tests/polymind/core_tools/test_llm_tools.py index 1c7d9c2..360f617 100644 --- a/tests/polymind/core_tools/test_llm_tools.py +++ b/tests/polymind/core_tools/test_llm_tools.py @@ -11,10 +11,7 @@ import pytest from polymind.core.message import Message -from polymind.core_tools.llm_tool import ( - OpenAIChatTool, - OpenAICodeGenerationTool, -) +from polymind.core_tools.llm_tool import OpenAIChatTool, OpenAICodeGenerationTool class TestOpenAIChatTool: