Skip to content

Commit

Permalink
import tests added for docs_src and examples
Browse files Browse the repository at this point in the history
  • Loading branch information
davorrunje committed Oct 9, 2024
1 parent 3d1f64e commit 7393ab1
Show file tree
Hide file tree
Showing 17 changed files with 155 additions and 45 deletions.
1 change: 1 addition & 0 deletions docs/docs/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ search:
- [UI](api/fastagency/base/UI.md)
- [WSGIProtocol](api/fastagency/base/WSGIProtocol.md)
- [WorkflowsProtocol](api/fastagency/base/WorkflowsProtocol.md)
- [check_register_decorator](api/fastagency/base/check_register_decorator.md)
- [run_workflow](api/fastagency/base/run_workflow.md)
- cli
- cli
Expand Down
11 changes: 11 additions & 0 deletions docs/docs/en/api/fastagency/base/check_register_decorator.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
# 0.5 - API
# 2 - Release
# 3 - Contributing
# 5 - Template Page
# 10 - Default
search:
boost: 0.5
---

::: fastagency.base.check_register_decorator
2 changes: 1 addition & 1 deletion docs/docs_src/getting_started/main_console.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from autogen.agentchat import ConversableAgent

from fastagency import UI, FastAgency, WorkflowsProtocol
from fastagency import UI, FastAgency
from fastagency.runtimes.autogen import AutoGenWorkflows
from fastagency.ui.console import ConsoleUI

Expand Down
2 changes: 1 addition & 1 deletion docs/docs_src/getting_started/main_mesop.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from autogen.agentchat import ConversableAgent

from fastagency import UI, FastAgency, WorkflowsProtocol
from fastagency import UI, FastAgency
from fastagency.runtimes.autogen import AutoGenWorkflows
from fastagency.ui.mesop import MesopUI

Expand Down
2 changes: 1 addition & 1 deletion docs/docs_src/tutorial/giphy/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from autogen import register_function
from autogen.agentchat import ConversableAgent

from fastagency import UI, FastAgency, WorkflowsProtocol
from fastagency import UI, FastAgency
from fastagency.api.openapi.client import OpenAPI
from fastagency.api.openapi.security import APIKeyQuery
from fastagency.messages import TextInput
Expand Down
2 changes: 1 addition & 1 deletion docs/docs_src/tutorial/giphy/simple_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from autogen import ConversableAgent, UserProxyAgent

from fastagency import UI, FastAgency, WorkflowsProtocol
from fastagency import UI, FastAgency
from fastagency.api.openapi.client import OpenAPI
from fastagency.api.openapi.security import APIKeyQuery
from fastagency.runtimes.autogen.autogen import AutoGenWorkflows
Expand Down
4 changes: 2 additions & 2 deletions docs/docs_src/user_guide/custom_user_interactions/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from autogen import register_function
from autogen.agentchat import ConversableAgent

from fastagency import UI, FastAgency, WorkflowsProtocol
from fastagency import UI, FastAgency
from fastagency.messages import MultipleChoice, SystemMessage, TextInput
from fastagency.runtimes.autogen.autogen import AutoGenWorkflows
from fastagency.ui.console import ConsoleUI
Expand All @@ -23,7 +23,7 @@


@wf.register(name="exam_practice", description="Student and teacher chat")
def exam_learning(ui: UI, workflow_uuid: str, param: dict[str, Any]) -> str:
def exam_learning(ui: UI, workflow_uuid: str, params: dict[str, Any]) -> str:
initial_message = ui.text_input(
sender="Workflow",
recipient="User",
Expand Down
2 changes: 1 addition & 1 deletion docs/docs_src/user_guide/external_rest_apis/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from autogen import UserProxyAgent
from autogen.agentchat import ConversableAgent

from fastagency import UI, FastAgency, WorkflowsProtocol
from fastagency import UI, FastAgency
from fastagency.api.openapi import OpenAPI
from fastagency.runtimes.autogen.autogen import AutoGenWorkflows
from fastagency.ui.console import ConsoleUI
Expand Down
2 changes: 1 addition & 1 deletion docs/docs_src/user_guide/external_rest_apis/security.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from autogen import UserProxyAgent
from autogen.agentchat import ConversableAgent

from fastagency import UI, FastAgency, WorkflowsProtocol
from fastagency import UI, FastAgency
from fastagency.api.openapi.client import OpenAPI
from fastagency.api.openapi.security import APIKeyHeader
from fastagency.runtimes.autogen.autogen import AutoGenWorkflows
Expand Down
2 changes: 1 addition & 1 deletion docs/docs_src/user_guide/ui/mesop/main_mesop.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import mesop as me
from autogen.agentchat import ConversableAgent

from fastagency import UI, FastAgency, WorkflowsProtocol
from fastagency import UI, FastAgency
from fastagency.runtimes.autogen import AutoGenWorkflows
from fastagency.ui.mesop import MesopUI
from fastagency.ui.mesop.styles import (
Expand Down
11 changes: 11 additions & 0 deletions fastagency/base.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import inspect
from collections.abc import Awaitable, Generator, Iterable, Iterator, Mapping
from contextlib import contextmanager
from typing import (
Expand Down Expand Up @@ -123,6 +124,16 @@ def register_api(
) -> None: ...


def check_register_decorator(func: Workflow) -> None:
# get names of all parameters in the function signature
sig = inspect.signature(func)
params = list(sig.parameters.keys())
if params != ["ui", "workflow_uuid", "params"]:
raise ValueError(
f"Expected function signature to be 'def func(ui: UI, workflow_uuid: str, params: dict[str, Any]) -> str', got {sig}"
)


@runtime_checkable
class AdapterProtocol(Protocol):
@classmethod
Expand Down
3 changes: 2 additions & 1 deletion fastagency/runtimes/autogen/autogen.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from autogen.agentchat import ConversableAgent
from autogen.io import IOStream

from ...base import UI, Workflow, WorkflowsProtocol
from ...base import UI, Workflow, WorkflowsProtocol, check_register_decorator
from ...logging import get_logger
from ...messages import (
AskingMessage,
Expand Down Expand Up @@ -278,6 +278,7 @@ def register(
self, name: str, description: str, *, fail_on_redefintion: bool = False
) -> Callable[[Workflow], Workflow]:
def decorator(func: Workflow) -> Workflow:
check_register_decorator(func)
if name in self._workflows:
if fail_on_redefintion:
raise ValueError(f"A workflow with name '{name}' already exists.")
Expand Down
27 changes: 27 additions & 0 deletions tests/docs_src/test_import.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import importlib
from pathlib import Path

import pytest

from ..helpers import add_to_sys_path, list_submodules

root_path = (Path(__file__).parents[2] / "docs").resolve()
module_name = "docs_src"


def test_list_submodules() -> None:
# Specify the name of the module you want to inspect

# Get the list of submodules for the specified module
submodules = list_submodules(module_name, include_path=root_path)

assert len(submodules) > 0
assert "docs_src" in submodules
assert "docs_src.getting_started" in submodules
assert "docs_src.getting_started.main_console" in submodules


@pytest.mark.parametrize("module", list_submodules(module_name, include_path=root_path))
def test_submodules(module: str) -> None:
with add_to_sys_path(root_path):
importlib.import_module(module)
27 changes: 27 additions & 0 deletions tests/examples/test_import.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import importlib
from pathlib import Path

import pytest

from ..helpers import add_to_sys_path, list_submodules

root_path = (Path(__file__).parents[2]).resolve()
module_name = "examples"


def test_list_submodules() -> None:
# Specify the name of the module you want to inspect

# Get the list of submodules for the specified module
submodules = list_submodules(module_name, include_path=root_path)

assert len(submodules) > 0
assert "examples" in submodules
assert "examples.cli" in submodules
assert "examples.cli.main_console" in submodules


@pytest.mark.parametrize("module", list_submodules(module_name, include_path=root_path))
def test_submodules(module: str) -> None:
with add_to_sys_path(root_path):
importlib.import_module(module)
63 changes: 62 additions & 1 deletion tests/helpers.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import functools
import importlib
import inspect
import pkgutil
import random
import sys
import types
from asyncio import iscoroutinefunction
from typing import Any, Callable, TypeVar
from collections.abc import Iterator
from contextlib import contextmanager
from pathlib import Path
from typing import Any, Callable, Optional, TypeVar

import pytest
import pytest_asyncio
Expand Down Expand Up @@ -170,3 +176,58 @@ def decorator(f: F) -> list[F]:
return retval

return decorator


@contextmanager
def add_to_sys_path(path: Optional[Path]) -> Iterator[None]:
if path is None:
yield
return

if not path.exists():
raise ValueError(f"Path {path} does not exist")

sys.path.append(str(path))
try:
yield
finally:
sys.path.remove(str(path))


def list_submodules(
module_name: str, *, include_path: Optional[Path] = None, include_root: bool = True
) -> list[str]:
"""List all submodules of a given module.
Args:
module_name (str): The name of the module to list submodules for.
include_path (Optional[Path], optional): The path to the module. Defaults to None.
include_root (bool, optional): Whether to include the root module in the list. Defaults to True.
Returns:
list: A list of submodule names.
"""
with add_to_sys_path(include_path):
try:
module = importlib.import_module(module_name)
except Exception:
return []

# Get the path of the module. This is necessary to find its submodules.
module_path = module.__path__

# Initialize an empty list to store the names of submodules
submodules = [module_name] if include_root else []

# Iterate over the submodules in the module's path
for _, name, ispkg in pkgutil.iter_modules(
module_path, prefix=f"{module_name}."
):
# Add the name of each submodule to the list
submodules.append(name)

if ispkg:
submodules.extend(list_submodules(name, include_root=False))

# Return the list of submodule names
return submodules
36 changes: 3 additions & 33 deletions tests/test_import.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import importlib
import pkgutil
import sys # Import the pkgutil module to work with the import system

import pytest
Expand All @@ -8,38 +7,7 @@
FastAgencyCLIPythonVersionError, # Import the importlib module to dynamically import modules
)


def list_submodules(module_name: str) -> list[str]:
"""List all submodules of a given module.
Args:
module_name (str): The name of the module to list submodules for.
Returns:
list: A list of submodule names.
"""
# Import the module dynamically using its name
try:
module = importlib.import_module(module_name)
except Exception:
return []

# Get the path of the module. This is necessary to find its submodules.
module_path = module.__path__

# Initialize an empty list to store the names of submodules
submodules = []

# Iterate over the submodules in the module's path
for _, name, ispkg in pkgutil.iter_modules(module_path, prefix=f"{module_name}."):
# Add the name of each submodule to the list
submodules.append(name)

if ispkg:
submodules.extend(list_submodules(name))

# Return the list of submodule names
return submodules
from .helpers import list_submodules


def test_list_submodules() -> None:
Expand All @@ -49,6 +17,8 @@ def test_list_submodules() -> None:
# Get the list of submodules for the specified module
submodules = list_submodules(module_name)

assert len(submodules) > 0
assert "fastagency" in submodules
assert "fastagency.ui" in submodules
assert "fastagency.ui.mesop" in submodules
assert "fastagency.ui.console.console" in submodules
Expand Down
3 changes: 2 additions & 1 deletion tests/ui/console/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import pytest

from fastagency.app import FastAgency
from fastagency.base import UI
from fastagency.runtimes.autogen import AutoGenWorkflows
from fastagency.ui.console import ConsoleUI

Expand All @@ -20,7 +21,7 @@ def app(import_string: str) -> Iterator[FastAgency]:
app = FastAgency(provider=wf, ui=console)

@wf.register(name="noop", description="No operation")
def noop(*args: Any, **kwargs: Any) -> str:
def noop(ui: UI, workflow_uuid: str, params: dict[str, Any]) -> str:
return "ok"

try:
Expand Down

0 comments on commit 7393ab1

Please sign in to comment.