-
Notifications
You must be signed in to change notification settings - Fork 43
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1056 from MichaelDecent/standalone_pkg1
Standalone_pkg1
- Loading branch information
Showing
17 changed files
with
445 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" | ||
|
78 changes: 78 additions & 0 deletions
78
pkgs/standards/swarmauri_tool_matplotlib/swarmauri_tool_matplotlib/MatplotlibCsvTool.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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": []} |
120 changes: 120 additions & 0 deletions
120
pkgs/standards/swarmauri_tool_matplotlib/swarmauri_tool_matplotlib/MatplotlibTool.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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": []} |
17 changes: 17 additions & 0 deletions
17
pkgs/standards/swarmauri_tool_matplotlib/swarmauri_tool_matplotlib/__init__.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
""" | ||
|
84 changes: 84 additions & 0 deletions
84
pkgs/standards/swarmauri_tool_matplotlib/tests/unit/MatplotlibCsvTool_unit_test.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
Oops, something went wrong.