Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Standalone_pkg1 #1056

Merged
merged 4 commits into from
Jan 9, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pkgs/standards/swarmauri_standard/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ full = [
#"transformers",
#"torch",
#"keras", "tf-keras",
"matplotlib"
#"matplotlib"
]

[tool.poetry.group.dev.dependencies]
Expand Down
55 changes: 55 additions & 0 deletions pkgs/standards/swarmauri_tool_matplotlib/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
[tool.poetry]
name = "swarmauri_tool_matplotlib"
version = "0.6.0.dev1"
description = "This repository includes an example of a First Class Swarmauri Example."
authors = ["Jacob Stewart <[email protected]>"]
license = "Apache-2.0"
readme = "README.md"
repository = "http://github.com/swarmauri/swarmauri-sdk"
classifiers = [
"License :: OSI Approved :: Apache Software License",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12"
]

[tool.poetry.dependencies]
python = ">=3.10,<3.13"

# Swarmauri
swarmauri_core = { path = "../../core" }
swarmauri_base = { path = "../../base" }

[tool.poetry.group.dev.dependencies]
flake8 = "^7.0"
pytest = "^8.0"
pytest-asyncio = ">=0.24.0"
pytest-xdist = "^3.6.1"
pytest-json-report = "^1.5.0"
python-dotenv = "*"
requests = "^2.32.3"

[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"

[tool.pytest.ini_options]
norecursedirs = ["combined", "scripts"]

markers = [
"test: standard test",
"unit: Unit tests",
"integration: Integration tests",
"acceptance: Acceptance tests",
"experimental: Experimental tests"
]
log_cli = true
log_cli_level = "INFO"
log_cli_format = "%(asctime)s [%(levelname)s] %(message)s"
log_cli_date_format = "%Y-%m-%d %H:%M:%S"
asyncio_default_fixture_loop_scope = "function"

[tool.poetry.plugins."swarmauri.tools"]
MatplotlibTool = "swarmauri_tool_matplotlib:MatplotlibTool"
MatplotlibCsvTool = "swarmauri_tool_matplotlib:MatplotlibCsvTool"

Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import pandas as pd
import matplotlib.pyplot as plt
import base64
from typing import List, Literal, Dict
from pydantic import Field
from swarmauri_standard.tools.Parameter import Parameter
from swarmauri_base.tools.ToolBase import ToolBase
from swarmauri_core.ComponentBase import ComponentBase


@ComponentBase.register_type(ToolBase, "MatplotlibCsvTool")
class MatplotlibCsvTool(ToolBase):
type: Literal["MatplotlibCsvTool"] = "MatplotlibCsvTool"
name: str = Field(
"MatplotlibCsvTool",
description="Tool to generate plots from CSV data using Matplotlib.",
)
description: str = Field(
"This tool reads data from a CSV file and generates a plot using Matplotlib.",
description="Description of the MatplotlibCsvTool",
)

parameters: List[Parameter] = Field(
default_factory=lambda: [
Parameter(
name="csv_file",
type="string",
description="The path to the CSV file containing the data.",
required=True,
),
Parameter(
name="x_column",
type="string",
description="The name of the column to use for the x-axis.",
required=True,
),
Parameter(
name="y_column",
type="string",
description="The name of the column to use for the y-axis.",
required=True,
),
Parameter(
name="output_file",
type="string",
description="The filename where the plot will be saved.",
required=True,
),
]
)

def __call__(
self, csv_file: str, x_column: str, y_column: str, output_file: str
) -> Dict[str, str]:
# Read data from CSV
data = pd.read_csv(csv_file)

# Check if columns exist in the DataFrame
if x_column not in data.columns or y_column not in data.columns:
raise ValueError(
f"Columns {x_column} and/or {y_column} not found in the CSV file."
)

# Generate plot
plt.figure(figsize=(10, 6))
plt.plot(data[x_column], data[y_column], marker="o")
plt.xlabel(x_column)
plt.ylabel(y_column)
plt.title(f"{y_column} vs {x_column}")
plt.grid(True)
plt.savefig(output_file)
plt.close()
print(f"Plot generated and saved to {output_file}")
# Encode the plot image as base64
with open(output_file, "rb") as image_file:
encoded_image = base64.b64encode(image_file.read()).decode("utf-8")

return {"img_path": output_file, "img_base64": encoded_image, "data": []}
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import base64
import matplotlib.pyplot as plt
from typing import List, Literal
from pydantic import Field
from swarmauri_base.tools.ToolBase import ToolBase
from swarmauri_standard.tools.Parameter import Parameter
from swarmauri_core.ComponentBase import ComponentBase


@ComponentBase.register_type(ToolBase, "MatplotlibTool")
class MatplotlibTool(ToolBase):
version: str = "1.0.0"
name: str = "MatplotlibTool"
description: str = (
"Generates a plot using Matplotlib library based on provided configuration."
)
type: Literal["MatplotlibTool"] = "MatplotlibTool"

parameters: List[Parameter] = Field(
default_factory=lambda: [
Parameter(
name="plot_type",
type="string",
description="Type of plot to generate (e.g., 'line', 'bar', 'scatter').",
required=True,
enum=["line", "bar", "scatter"],
),
Parameter(
name="x_data",
type="list<float>",
description="X-axis data for the plot.",
required=True,
),
Parameter(
name="y_data",
type="list<float>",
description="Y-axis data for the plot.",
required=True,
),
Parameter(
name="title",
type="string",
description="Title of the plot.",
required=False,
default="",
),
Parameter(
name="x_label",
type="string",
description="Label for the X-axis.",
required=False,
default="",
),
Parameter(
name="y_label",
type="string",
description="Label for the Y-axis.",
required=False,
default="",
),
Parameter(
name="save_path",
type="string",
description="Path to save the generated plot image.",
required=False,
default="plot.png",
),
]
)

def __call__(
self,
plot_type: str,
x_data: List[float],
y_data: List[float],
title: str = "",
x_label: str = "",
y_label: str = "",
save_path: str = "plot.png",
):
"""
Generates a plot using Matplotlib based on provided configuration.

Parameters:
plot_type (str): The type of the plot ('line', 'bar', 'scatter').
x_data (List[float]): X-axis data for the plot.
y_data (List[float]): Y-axis data for the plot.
title (str): Title of the plot.
x_label (str): Label for the X-axis.
y_label (str): Label for the Y-axis.
save_path (str): Path to save the generated plot image.

Returns:
str: Path where the plot image is saved.
"""
plt.figure()

if plot_type == "line":
plt.plot(x_data, y_data)
elif plot_type == "bar":
plt.bar(x_data, y_data)
elif plot_type == "scatter":
plt.scatter(x_data, y_data)
else:
raise ValueError(f"Unsupported plot type: {plot_type}")

if title:
plt.title(title)
if x_label:
plt.xlabel(x_label)
if y_label:
plt.ylabel(y_label)

plt.savefig(save_path)
plt.close()

with open(save_path, "rb") as image_file:
encoded_image = base64.b64encode(image_file.read()).decode("utf-8")

return {"img_path": save_path, "img_base64": encoded_image, "data": []}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from .MatplotlibCsvTool import MatplotlibCsvTool
from .MatplotlibTool import MatplotlibTool
__version__ = "0.6.0.dev26"
__long_desc__ = """

# Swarmauri Matplotlib Based Components

Components Included:
- MatplotlibTool
- MatplotlibCsvTool

Visit us at: https://swarmauri.com
Follow us at: https://github.com/swarmauri
Star us at: https://github.com/swarmauri/swarmauri-sdk

"""

Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import os
from tempfile import NamedTemporaryFile

import pytest
from swarmauri_tool_matplotlib.MatplotlibCsvTool import MatplotlibCsvTool as Tool


@pytest.mark.unit
def test_ubc_resource():
tool = Tool()
assert tool.resource == "Tool"


@pytest.mark.unit
def test_ubc_type():
assert Tool().type == "MatplotlibCsvTool"


@pytest.mark.unit
def test_initialization():
tool = Tool()
assert type(tool.id) == str


@pytest.mark.unit
def test_serialization():
tool = Tool()
assert tool.id == Tool.model_validate_json(tool.model_dump_json()).id


@pytest.mark.parametrize(
"csv_content, x_column, y_column, expected_error",
[
(
"x,y\n1,2\n3,4\n5,6", # CSV content
"x", # x_column
"y", # y_column
None, # No error expected
),
(
"a,b\n1,2\n3,4\n5,6", # CSV content
"x", # x_column
"y", # y_column
ValueError, # Error expected due to missing columns
),
(
"x,z\n1,2\n3,4\n5,6", # CSV content
"x", # x_column
"y", # y_column
ValueError, # Error expected due to missing y_column
),
],
)
@pytest.mark.unit
def test_call(csv_content, x_column, y_column, expected_error):
with NamedTemporaryFile(delete=False, suffix=".csv") as csv_file:
csv_file.write(csv_content.encode())
csv_file_path = csv_file.name

with NamedTemporaryFile(delete=False, suffix=".png") as output_file:
output_file_path = output_file.name

tool = Tool()
expected_keys = {"img_path", "img_base64", "data"}

if expected_error:
with pytest.raises(expected_error):
tool(csv_file_path, x_column, y_column, output_file_path)
else:
result = tool(csv_file_path, x_column, y_column, output_file_path)
assert isinstance(
result, dict
), f"Expected dict, but got {type(result).__name__}"
assert expected_keys.issubset(
result.keys()
), f"Expected keys {expected_keys} but got {result.keys()}"
assert isinstance(
result.get("data"), list
), f"Expected list, but got {type(result).__name__}"
assert os.path.exists(output_file_path)

os.remove(csv_file_path)
if os.path.exists(output_file_path):
os.remove(output_file_path)
Loading
Loading