From 4e3f832dc3e4b80adb616c1038611a04959db492 Mon Sep 17 00:00:00 2001 From: merwanehamadi Date: Tue, 20 Jun 2023 06:47:59 -0700 Subject: [PATCH] Remove config singleton (#4737) --- autogpt/config/config.py | 3 +- docs/challenges/building_challenges.md | 4 +-- requirements.txt | 1 - .../challenge_decorator.py | 9 ++---- tests/conftest.py | 3 ++ tests/integration/agent_factory.py | 8 +---- .../memory/test_json_file_memory.py | 3 +- tests/integration/test_image_gen.py | 5 ++- tests/integration/test_setup.py | 9 +++--- tests/integration/test_web_selenium.py | 3 +- tests/utils.py | 32 ------------------- 11 files changed, 16 insertions(+), 64 deletions(-) diff --git a/autogpt/config/config.py b/autogpt/config/config.py index 3231f560..5e0999b1 100644 --- a/autogpt/config/config.py +++ b/autogpt/config/config.py @@ -8,10 +8,9 @@ from auto_gpt_plugin_template import AutoGPTPluginTemplate from colorama import Fore import autogpt -from autogpt.singleton import Singleton -class Config(metaclass=Singleton): +class Config: """ Configuration class to store the state of bools for different scripts access. """ diff --git a/docs/challenges/building_challenges.md b/docs/challenges/building_challenges.md index f50b0ea9..1a0f5a8c 100644 --- a/docs/challenges/building_challenges.md +++ b/docs/challenges/building_challenges.md @@ -85,8 +85,6 @@ import yaml from autogpt.commands.file_operations import read_file, write_to_file from tests.integration.agent_utils import run_interaction_loop from tests.challenges.utils import run_multiple_times -from tests.utils import requires_api_key - def input_generator(input_sequence: list) -> Generator[str, None, None]: """ @@ -100,7 +98,7 @@ def input_generator(input_sequence: list) -> Generator[str, None, None]: @pytest.mark.skip("This challenge hasn't been beaten yet.") @pytest.mark.vcr -@requires_api_key("OPENAI_API_KEY") +@pytest.mark.requires_openai_api_key def test_information_retrieval_challenge_a(kubernetes_agent, monkeypatch) -> None: """ Test the challenge_a function in a given agent by mocking user inputs diff --git a/requirements.txt b/requirements.txt index 8c171f83..d8315c73 100644 --- a/requirements.txt +++ b/requirements.txt @@ -62,4 +62,3 @@ pytest-mock vcrpy @ git+https://github.com/Significant-Gravitas/vcrpy.git@master pytest-recording pytest-xdist -flaky diff --git a/tests/challenges/challenge_decorator/challenge_decorator.py b/tests/challenges/challenge_decorator/challenge_decorator.py index 52d796c0..3d72ff9b 100644 --- a/tests/challenges/challenge_decorator/challenge_decorator.py +++ b/tests/challenges/challenge_decorator/challenge_decorator.py @@ -3,7 +3,6 @@ from functools import wraps from typing import Any, Callable, Optional import pytest -from flaky import flaky # type: ignore from tests.challenges.challenge_decorator.challenge import Challenge from tests.challenges.challenge_decorator.challenge_utils import create_challenge @@ -11,7 +10,6 @@ from tests.challenges.challenge_decorator.score_utils import ( get_scores, update_new_score, ) -from tests.utils import requires_api_key MAX_LEVEL_TO_IMPROVE_ON = ( 1 # we will attempt to beat 1 level above the current level for now. @@ -20,13 +18,10 @@ MAX_LEVEL_TO_IMPROVE_ON = ( CHALLENGE_FAILED_MESSAGE = "Challenges can sometimes fail randomly, please run this test again and if it fails reach out to us on https://discord.gg/autogpt in the 'challenges' channel to let us know the challenge you're struggling with." -def challenge( - max_runs: int = 2, min_passes: int = 1, api_key: str = "OPENAI_API_KEY" -) -> Callable[[Callable[..., Any]], Callable[..., None]]: +def challenge() -> Callable[[Callable[..., Any]], Callable[..., None]]: def decorator(func: Callable[..., Any]) -> Callable[..., None]: - @requires_api_key(api_key) + @pytest.mark.requires_openai_api_key @pytest.mark.vcr - @flaky(max_runs=max_runs, min_passes=min_passes) @wraps(func) def wrapper(*args: Any, **kwargs: Any) -> None: run_remaining = MAX_LEVEL_TO_IMPROVE_ON if Challenge.BEAT_CHALLENGES else 1 diff --git a/tests/conftest.py b/tests/conftest.py index db0eced0..15a3c296 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -50,6 +50,9 @@ def config( temp_plugins_config_file: str, mocker: MockerFixture, workspace: Workspace ) -> Config: config = Config() + if not config.openai_api_key: + config.set_openai_api_key("sk-dummy") + config.plugins_dir = "tests/unit/data/test_plugins" config.plugins_config_file = temp_plugins_config_file config.load_plugins_config() diff --git a/tests/integration/agent_factory.py b/tests/integration/agent_factory.py index e6702b66..0edfb371 100644 --- a/tests/integration/agent_factory.py +++ b/tests/integration/agent_factory.py @@ -11,16 +11,10 @@ from autogpt.workspace import Workspace @pytest.fixture def agent_test_config(config: Config): - was_continuous_mode = config.continuous_mode - was_temperature = config.temperature - was_plain_output = config.plain_output config.set_continuous_mode(False) config.set_temperature(0) config.plain_output = True - yield config - config.set_continuous_mode(was_continuous_mode) - config.set_temperature(was_temperature) - config.plain_output = was_plain_output + return config @pytest.fixture diff --git a/tests/integration/memory/test_json_file_memory.py b/tests/integration/memory/test_json_file_memory.py index ab3996de..e60a0766 100644 --- a/tests/integration/memory/test_json_file_memory.py +++ b/tests/integration/memory/test_json_file_memory.py @@ -6,7 +6,6 @@ import pytest from autogpt.config import Config from autogpt.memory.vector import JSONFileMemory, MemoryItem from autogpt.workspace import Workspace -from tests.utils import requires_api_key @pytest.fixture(autouse=True) @@ -99,7 +98,7 @@ def test_json_memory_load_index(config: Config, memory_item: MemoryItem): @pytest.mark.vcr -@requires_api_key("OPENAI_API_KEY") +@pytest.mark.requires_openai_api_key def test_json_memory_get_relevant(config: Config, patched_api_requestor: None) -> None: index = JSONFileMemory(config) mem1 = MemoryItem.from_text_file("Sample text", "sample.txt", config) diff --git a/tests/integration/test_image_gen.py b/tests/integration/test_image_gen.py index a606d8da..8cdcfd98 100644 --- a/tests/integration/test_image_gen.py +++ b/tests/integration/test_image_gen.py @@ -8,7 +8,6 @@ from PIL import Image from autogpt.agent.agent import Agent from autogpt.commands.image_gen import generate_image, generate_image_with_sd_webui -from tests.utils import requires_api_key @pytest.fixture(params=[256, 512, 1024]) @@ -17,7 +16,7 @@ def image_size(request): return request.param -@requires_api_key("OPENAI_API_KEY") +@pytest.mark.requires_openai_api_key @pytest.mark.vcr def test_dalle(agent: Agent, workspace, image_size, patched_api_requestor): """Test DALL-E image generation.""" @@ -32,7 +31,7 @@ def test_dalle(agent: Agent, workspace, image_size, patched_api_requestor): @pytest.mark.xfail( reason="The image is too big to be put in a cassette for a CI pipeline. We're looking into a solution." ) -@requires_api_key("HUGGINGFACE_API_TOKEN") +@pytest.mark.requires_huggingface_api_key @pytest.mark.parametrize( "image_model", ["CompVis/stable-diffusion-v1-4", "stabilityai/stable-diffusion-2-1"], diff --git a/tests/integration/test_setup.py b/tests/integration/test_setup.py index ed7eb8fd..b74eebaf 100644 --- a/tests/integration/test_setup.py +++ b/tests/integration/test_setup.py @@ -4,11 +4,10 @@ import pytest from autogpt.config.ai_config import AIConfig from autogpt.setup import generate_aiconfig_automatic, prompt_user -from tests.utils import requires_api_key @pytest.mark.vcr -@requires_api_key("OPENAI_API_KEY") +@pytest.mark.requires_openai_api_key def test_generate_aiconfig_automatic_default(patched_api_requestor, config): user_inputs = [""] with patch("autogpt.utils.session.prompt", side_effect=user_inputs): @@ -21,7 +20,7 @@ def test_generate_aiconfig_automatic_default(patched_api_requestor, config): @pytest.mark.vcr -@requires_api_key("OPENAI_API_KEY") +@pytest.mark.requires_openai_api_key def test_generate_aiconfig_automatic_typical(patched_api_requestor, config): user_prompt = "Help me create a rock opera about cybernetic giraffes" ai_config = generate_aiconfig_automatic(user_prompt, config) @@ -33,7 +32,7 @@ def test_generate_aiconfig_automatic_typical(patched_api_requestor, config): @pytest.mark.vcr -@requires_api_key("OPENAI_API_KEY") +@pytest.mark.requires_openai_api_key def test_generate_aiconfig_automatic_fallback(patched_api_requestor, config): user_inputs = [ "T&GF£OIBECC()!*", @@ -54,7 +53,7 @@ def test_generate_aiconfig_automatic_fallback(patched_api_requestor, config): @pytest.mark.vcr -@requires_api_key("OPENAI_API_KEY") +@pytest.mark.requires_openai_api_key def test_prompt_user_manual_mode(patched_api_requestor, config): user_inputs = [ "--manual", diff --git a/tests/integration/test_web_selenium.py b/tests/integration/test_web_selenium.py index baf3653c..f98b2971 100644 --- a/tests/integration/test_web_selenium.py +++ b/tests/integration/test_web_selenium.py @@ -3,11 +3,10 @@ from pytest_mock import MockerFixture from autogpt.agent.agent import Agent from autogpt.commands.web_selenium import browse_website -from tests.utils import requires_api_key @pytest.mark.vcr -@requires_api_key("OPENAI_API_KEY") +@pytest.mark.requires_openai_api_key def test_browse_website(agent: Agent, patched_api_requestor: MockerFixture): url = "https://barrel-roll.com" question = "How to execute a barrel roll" diff --git a/tests/utils.py b/tests/utils.py index 2603dfe4..fac2816a 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -1,39 +1,7 @@ -import functools import os -from contextlib import contextmanager import pytest -from autogpt.config import Config - - -@contextmanager -def dummy_openai_api_key(): - # even when we record the VCR cassettes, openAI wants an API key - config = Config() - original_api_key = config.openai_api_key - config.set_openai_api_key("sk-dummy") - - try: - yield - finally: - config.set_openai_api_key(original_api_key) - - -def requires_api_key(env_var): - def decorator(func): - @functools.wraps(func) - def wrapper(*args, **kwargs): - if env_var == "OPENAI_API_KEY": - if not os.environ.get(env_var) and env_var == "OPENAI_API_KEY": - with dummy_openai_api_key(): - return func(*args, **kwargs) - return func(*args, **kwargs) - - return wrapper - - return decorator - def skip_in_ci(test_function): return pytest.mark.skipif(