lionagi 0.6.0__py3-none-any.whl → 0.6.1__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
lionagi/__init__.py CHANGED
@@ -2,6 +2,7 @@
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
5
+ from lionagi.operations import types as op
5
6
  from lionagi.operatives import types as ops_types
6
7
  from lionagi.protocols import types as types
7
8
  from lionagi.service.imodel import iModel
@@ -17,5 +18,6 @@ __all__ = (
17
18
  "LiteiModel",
18
19
  "types",
19
20
  "ops_types",
21
+ "op",
20
22
  "__version__",
21
23
  )
@@ -27,9 +27,9 @@ from .prompt import EXPANSION_PROMPT, PLAN_PROMPT
27
27
  class PlanOperation(BaseModel):
28
28
  """
29
29
  Stores all relevant outcomes for a multi-step Plan:
30
- * initial: The result of the initial plan prompt
31
- * plan: A list of plan steps (Instruct objects) generated from the initial planning
32
- * execute: Any responses from executing those plan steps
30
+ * initial: The result of the initial plan prompt
31
+ * plan: A list of plan steps (Instruct objects) generated from the initial planning
32
+ * execute: Any responses from executing those plan steps
33
33
  """
34
34
 
35
35
  initial: Any
@@ -8,8 +8,8 @@ from typing import Any
8
8
 
9
9
  from pydantic import BaseModel, Field
10
10
 
11
- from lionagi import Branch
12
11
  from lionagi.operatives.types import Instruct
12
+ from lionagi.session.branch import Branch
13
13
 
14
14
  from .prompt import PROMPT
15
15
  from .utils import parse_selection, parse_to_representation
@@ -10,9 +10,25 @@ from lionagi.operatives.instruct.instruct import (
10
10
  LIST_INSTRUCT_FIELD_MODEL,
11
11
  Instruct,
12
12
  )
13
- from lionagi.protocols.types import FieldModel, SchemaModel
13
+ from lionagi.operatives.types import FieldModel, SchemaModel
14
14
  from lionagi.session.session import Branch, Session
15
- from lionagi.utils import RCallParams
15
+
16
+
17
+ class RCallParams(SchemaModel):
18
+ """Parameters for remote function calls."""
19
+
20
+ timeout: float = Field(
21
+ default=60, description="Timeout for remote function call"
22
+ )
23
+ max_retries: int = Field(
24
+ default=3, description="Maximum number of retries"
25
+ )
26
+ retry_delay: float = Field(
27
+ default=0.5, description="Delay between retries"
28
+ )
29
+ retry_backoff: float = Field(
30
+ default=2, description="Backoff factor for retry delay"
31
+ )
16
32
 
17
33
 
18
34
  class StrategyParams(SchemaModel):
@@ -2,6 +2,12 @@
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
5
- from .brainstorm import *
6
- from .plan import *
7
- from .select import *
5
+ from .brainstorm.brainstorm import brainstorm
6
+ from .plan.plan import plan
7
+ from .select.select import select
8
+
9
+ __all__ = (
10
+ "brainstorm",
11
+ "plan",
12
+ "select",
13
+ )
@@ -7,7 +7,7 @@ from typing import Any, Self
7
7
 
8
8
  from pydantic import Field, model_validator
9
9
 
10
- from lionagi.protocols.types import Event, EventStatus
10
+ from lionagi.protocols.generic.event import Event, EventStatus
11
11
  from lionagi.utils import is_coro_func
12
12
 
13
13
  from .tool import Tool
@@ -4,13 +4,10 @@
4
4
 
5
5
  from typing import Any
6
6
 
7
- from lionagi.protocols.types import (
8
- ActionRequest,
9
- EventStatus,
10
- Execution,
11
- Log,
12
- Manager,
13
- )
7
+ from lionagi.protocols._concepts import Manager
8
+ from lionagi.protocols.generic.event import EventStatus, Execution
9
+ from lionagi.protocols.generic.log import Log
10
+ from lionagi.protocols.messages.action_request import ActionRequest
14
11
  from lionagi.utils import to_list
15
12
 
16
13
  from .function_calling import FunctionCalling
@@ -10,7 +10,7 @@ from pydantic import Field, field_validator, model_validator
10
10
 
11
11
  from lionagi.libs.schema.function_to_schema import function_to_schema
12
12
  from lionagi.libs.validate.common_field_validators import validate_callable
13
- from lionagi.protocols.types import Element
13
+ from lionagi.protocols.generic.element import Element
14
14
 
15
15
  __all__ = (
16
16
  "Tool",
File without changes
@@ -0,0 +1,95 @@
1
+ # Copyright (c) 2023 - 2024, HaiyangLi <quantocean.li at gmail dot com>
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ import logging
6
+ from typing import Any, Protocol, TypeVar, runtime_checkable
7
+
8
+ from typing_extensions import get_protocol_members
9
+
10
+ T = TypeVar("T")
11
+
12
+ __all__ = (
13
+ "Adapter",
14
+ "ADAPTER_MEMBERS",
15
+ "AdapterRegistry",
16
+ )
17
+
18
+
19
+ @runtime_checkable
20
+ class Adapter(Protocol):
21
+
22
+ obj_key: str
23
+
24
+ @classmethod
25
+ def from_obj(
26
+ cls,
27
+ subj_cls: type[T],
28
+ obj: Any,
29
+ /,
30
+ *,
31
+ many: bool,
32
+ **kwargs,
33
+ ) -> dict | list[dict]: ...
34
+
35
+ @classmethod
36
+ def to_obj(
37
+ cls,
38
+ subj: T,
39
+ /,
40
+ *,
41
+ many: bool,
42
+ **kwargs,
43
+ ) -> Any: ...
44
+
45
+
46
+ ADAPTER_MEMBERS = get_protocol_members(Adapter) # duck typing
47
+
48
+
49
+ class AdapterRegistry:
50
+
51
+ _adapters: dict[str, Adapter] = {}
52
+
53
+ @classmethod
54
+ def list_adapters(cls) -> list[tuple[str | type, ...]]:
55
+ return list(cls._adapters.keys())
56
+
57
+ @classmethod
58
+ def register(cls, adapter: type[Adapter]) -> None:
59
+ for member in ADAPTER_MEMBERS:
60
+ if not hasattr(adapter, member):
61
+ _str = getattr(adapter, "obj_key", None) or repr(adapter)
62
+ _str = _str[:50] if len(_str) > 50 else _str
63
+ raise AttributeError(
64
+ f"Adapter {_str} missing required methods."
65
+ )
66
+
67
+ if isinstance(adapter, type):
68
+ cls._adapters[adapter.obj_key] = adapter()
69
+ else:
70
+ cls._adapters[adapter.obj_key] = adapter
71
+
72
+ @classmethod
73
+ def get(cls, obj_key: type | str) -> Adapter:
74
+ try:
75
+ return cls._adapters[obj_key]
76
+ except Exception as e:
77
+ logging.error(f"Error getting adapter for {obj_key}. Error: {e}")
78
+
79
+ @classmethod
80
+ def adapt_from(
81
+ cls, subj_cls: type[T], obj: Any, obj_key: type | str, **kwargs
82
+ ) -> dict | list[dict]:
83
+ try:
84
+ return cls.get(obj_key).from_obj(subj_cls, obj, **kwargs)
85
+ except Exception as e:
86
+ logging.error(f"Error adapting data from {obj_key}. Error: {e}")
87
+ raise e
88
+
89
+ @classmethod
90
+ def adapt_to(cls, subj: T, obj_key: type | str, **kwargs) -> Any:
91
+ try:
92
+ return cls.get(obj_key).to_obj(subj, **kwargs)
93
+ except Exception as e:
94
+ logging.error(f"Error adapting data to {obj_key}. Error: {e}")
95
+ raise e
@@ -0,0 +1,101 @@
1
+ import json
2
+ import logging
3
+ from pathlib import Path
4
+
5
+ from lionagi.protocols._concepts import Collective
6
+
7
+ from .adapter import Adapter, T
8
+
9
+
10
+ class JsonAdapter(Adapter):
11
+
12
+ obj_key = "json"
13
+
14
+ @classmethod
15
+ def from_obj(
16
+ cls,
17
+ subj_cls: type[T],
18
+ obj: str,
19
+ /,
20
+ *,
21
+ many: bool = False,
22
+ **kwargs,
23
+ ) -> dict | list[dict]:
24
+ """
25
+ kwargs for json.loads(s, **kwargs)
26
+ """
27
+ result = json.loads(obj, **kwargs)
28
+ if many:
29
+ return result if isinstance(result, list) else [result]
30
+ return (
31
+ result[0]
32
+ if isinstance(result, list) and len(result) > 0
33
+ else result
34
+ )
35
+
36
+ @classmethod
37
+ def to_obj(
38
+ cls,
39
+ subj: T,
40
+ *,
41
+ many: bool = False,
42
+ **kwargs,
43
+ ):
44
+ """
45
+ kwargs for json.dumps(obj, **kwargs)
46
+ """
47
+ if many:
48
+ if isinstance(subj, Collective):
49
+ return json.dumps([i.to_dict() for i in subj], **kwargs)
50
+ return json.dumps([subj.to_dict()], **kwargs)
51
+ return json.dumps(subj.to_dict(), **kwargs)
52
+
53
+
54
+ class JsonFileAdapter(Adapter):
55
+
56
+ obj_key = ".json"
57
+
58
+ @classmethod
59
+ def from_obj(
60
+ cls,
61
+ subj_cls: type[T],
62
+ obj: str | Path,
63
+ /,
64
+ *,
65
+ many: bool = False,
66
+ **kwargs,
67
+ ) -> dict | list[dict]:
68
+ """
69
+ kwargs for json.load(fp, **kwargs)
70
+ """
71
+ with open(obj) as f:
72
+ result = json.load(f, **kwargs)
73
+ if many:
74
+ return result if isinstance(result, list) else [result]
75
+ return (
76
+ result[0]
77
+ if isinstance(result, list) and len(result) > 0
78
+ else result
79
+ )
80
+
81
+ @classmethod
82
+ def to_obj(
83
+ cls,
84
+ subj: T,
85
+ /,
86
+ *,
87
+ fp: str | Path,
88
+ many: bool = False,
89
+ **kwargs,
90
+ ):
91
+ """
92
+ kwargs for json.dump(obj, fp, **kwargs)
93
+ """
94
+ if many:
95
+ if isinstance(subj, Collective):
96
+ json.dump([i.to_dict() for i in subj], fp=fp, **kwargs)
97
+ return
98
+ json.dump([subj.to_dict()], fp=fp, **kwargs)
99
+ return
100
+ json.dump(subj.to_dict(), fp=fp, **kwargs)
101
+ logging.info(f"Successfully saved data to {fp}")
File without changes
@@ -0,0 +1,50 @@
1
+ import logging
2
+ from pathlib import Path
3
+
4
+ import pandas as pd
5
+
6
+ from lionagi.protocols._concepts import Collective
7
+
8
+ from ..adapter import Adapter, T
9
+
10
+
11
+ class CSVFileAdapter(Adapter):
12
+ obj_key = ".csv"
13
+
14
+ @classmethod
15
+ def from_obj(
16
+ cls,
17
+ subj_cls: type[T],
18
+ obj: str | Path,
19
+ /,
20
+ *,
21
+ many: bool = False,
22
+ **kwargs,
23
+ ) -> list[dict]:
24
+ """kwargs for pd.read_csv"""
25
+ df: pd.DataFrame = pd.read_csv(obj, **kwargs)
26
+ dicts_ = df.to_dict(orient="records")
27
+ return dicts_[0] if not many else dicts_
28
+
29
+ @classmethod
30
+ def to_obj(
31
+ cls,
32
+ subj: T,
33
+ /,
34
+ *,
35
+ fp: str | Path,
36
+ many: bool = False,
37
+ **kwargs,
38
+ ):
39
+ """kwargs for pd.DataFrame.to_csv"""
40
+ kwargs["index"] = False
41
+ if many:
42
+ if isinstance(subj, Collective):
43
+ pd.DataFrame([i.to_dict() for i in subj]).to_csv(fp, **kwargs)
44
+ logging.info(f"Successfully saved data to {fp}")
45
+ return
46
+ pd.DataFrame([subj.to_dict()]).to_csv(fp, **kwargs)
47
+ logging.info(f"Successfully saved data to {fp}")
48
+ return
49
+ pd.DataFrame([subj.to_dict()]).to_csv(fp, **kwargs)
50
+ logging.info(f"Successfully saved data to {fp}")
@@ -0,0 +1,52 @@
1
+ import logging
2
+ from pathlib import Path
3
+
4
+ import pandas as pd
5
+
6
+ from lionagi.protocols._concepts import Collective
7
+
8
+ from ..adapter import Adapter, T
9
+
10
+
11
+ class ExcelFileAdapter(Adapter):
12
+ obj_key = ".xlsx"
13
+
14
+ @classmethod
15
+ def from_obj(
16
+ cls,
17
+ subj_cls: type[T],
18
+ obj: str | Path,
19
+ /,
20
+ *,
21
+ many: bool = False,
22
+ **kwargs,
23
+ ) -> list[dict]:
24
+ """kwargs for pd.read_csv"""
25
+ df: pd.DataFrame = pd.read_excel(obj, **kwargs)
26
+ dicts_ = df.to_dict(orient="records")
27
+ return dicts_[0] if not many else dicts_
28
+
29
+ @classmethod
30
+ def to_obj(
31
+ cls,
32
+ subj: T,
33
+ /,
34
+ *,
35
+ fp: str | Path,
36
+ many: bool = False,
37
+ **kwargs,
38
+ ):
39
+ """kwargs for pd.DataFrame.to_csv"""
40
+ kwargs["index"] = False
41
+ if many:
42
+ if isinstance(subj, Collective):
43
+ pd.DataFrame([i.to_dict() for i in subj]).to_excel(
44
+ fp, **kwargs
45
+ )
46
+ logging.info(f"Successfully saved data to {fp}")
47
+ return
48
+ pd.DataFrame([subj.to_dict()]).to_excel(fp, **kwargs)
49
+ logging.info(f"Successfully saved data to {fp}")
50
+ return
51
+ pd.DataFrame([subj.to_dict()]).to_excel(fp, **kwargs)
52
+ logging.info(f"Successfully saved data to {fp}")
@@ -0,0 +1,31 @@
1
+ from datetime import datetime
2
+
3
+ import pandas as pd
4
+
5
+ from ..adapter import Adapter, T
6
+
7
+
8
+ class PandasDataFrameAdapter(Adapter):
9
+
10
+ obj_key = "pd_dataframe"
11
+ alias = ("pandas_dataframe", "pd.DataFrame", "pd_dataframe")
12
+
13
+ @classmethod
14
+ def from_obj(
15
+ cls, subj_cls: type[T], obj: pd.DataFrame, /, **kwargs
16
+ ) -> list[dict]:
17
+ """kwargs for pd.DataFrame.to_dict"""
18
+ return obj.to_dict(orient="records", **kwargs)
19
+
20
+ @classmethod
21
+ def to_obj(cls, subj: list[T], /, **kwargs) -> pd.DataFrame:
22
+ """kwargs for pd.DataFrame"""
23
+ out_ = []
24
+ for i in subj:
25
+ _dict = i.to_dict()
26
+ _dict["created_at"] = datetime.fromtimestamp(_dict["created_at"])
27
+ out_.append(_dict)
28
+ df = pd.DataFrame(out_, **kwargs)
29
+ if "created_at" in df.columns:
30
+ df["created_at"] = pd.to_datetime(df["created_at"])
31
+ return df
@@ -0,0 +1,17 @@
1
+ import pandas as pd
2
+
3
+ from ..adapter import Adapter, T
4
+
5
+
6
+ class PandasSeriesAdapter(Adapter):
7
+
8
+ obj_key = "pd_series"
9
+ alias = ("pandas_series", "pd.series", "pd_series")
10
+
11
+ @classmethod
12
+ def from_obj(cls, subj_cls: type[T], obj: pd.Series, /, **kwargs) -> dict:
13
+ return obj.to_dict(**kwargs)
14
+
15
+ @classmethod
16
+ def to_obj(cls, subj: T, /, **kwargs) -> pd.Series:
17
+ return pd.Series(subj.to_dict(), **kwargs)
@@ -0,0 +1,18 @@
1
+ from .adapter import ADAPTER_MEMBERS, Adapter, AdapterRegistry
2
+ from .json_adapter import JsonAdapter, JsonFileAdapter
3
+ from .pandas_.csv_adapter import CSVFileAdapter
4
+ from .pandas_.excel_adapter import ExcelFileAdapter
5
+ from .pandas_.pd_dataframe_adapter import PandasDataFrameAdapter
6
+ from .pandas_.pd_series_adapter import PandasSeriesAdapter
7
+
8
+ __all__ = (
9
+ "Adapter",
10
+ "AdapterRegistry",
11
+ "ADAPTER_MEMBERS",
12
+ "JsonAdapter",
13
+ "JsonFileAdapter",
14
+ "CSVFileAdapter",
15
+ "PandasSeriesAdapter",
16
+ "PandasDataFrameAdapter",
17
+ "ExcelFileAdapter",
18
+ )
@@ -27,8 +27,12 @@ from typing_extensions import override
27
27
  from lionagi._errors import ItemExistsError, ItemNotFoundError
28
28
  from lionagi.utils import UNDEFINED, is_same_dtype, to_list
29
29
 
30
- from .._adapter import Adapter, AdapterRegistry, PileAdapterRegistry
31
30
  from .._concepts import Observable
31
+ from ..adapters.adapter import Adapter, AdapterRegistry
32
+ from ..adapters.json_adapter import JsonAdapter, JsonFileAdapter
33
+ from ..adapters.pandas_.csv_adapter import CSVFileAdapter
34
+ from ..adapters.pandas_.excel_adapter import ExcelFileAdapter
35
+ from ..adapters.pandas_.pd_dataframe_adapter import PandasDataFrameAdapter
32
36
  from .element import ID, Collective, E, Element, IDType, validate_order
33
37
  from .progression import Progression
34
38
 
@@ -36,6 +40,23 @@ D = TypeVar("D")
36
40
  T = TypeVar("T", bound=E)
37
41
 
38
42
 
43
+ PILE_DEFAULT_ADAPTERS = (
44
+ JsonAdapter,
45
+ JsonFileAdapter,
46
+ CSVFileAdapter,
47
+ ExcelFileAdapter,
48
+ PandasDataFrameAdapter,
49
+ )
50
+
51
+
52
+ class PileAdapterRegistry(AdapterRegistry):
53
+ pass
54
+
55
+
56
+ for i in PILE_DEFAULT_ADAPTERS:
57
+ PileAdapterRegistry.register(i)
58
+
59
+
39
60
  __all__ = (
40
61
  "Pile",
41
62
  "pile",
@@ -9,10 +9,26 @@ from pydantic import field_validator
9
9
 
10
10
  from lionagi._class_registry import LION_CLASS_REGISTRY
11
11
 
12
- from .._adapter import AdapterRegistry, NodeAdapterRegistry
13
12
  from .._concepts import Relational
13
+ from ..adapters.adapter import AdapterRegistry
14
+ from ..adapters.json_adapter import JsonAdapter, JsonFileAdapter
15
+ from ..adapters.pandas_.pd_series_adapter import PandasSeriesAdapter
14
16
  from ..generic.element import Element
15
17
 
18
+ NODE_DEFAULT_ADAPTERS = (
19
+ JsonAdapter,
20
+ JsonFileAdapter,
21
+ PandasSeriesAdapter,
22
+ )
23
+
24
+
25
+ class NodeAdapterRegistry(AdapterRegistry):
26
+ pass
27
+
28
+
29
+ for i in NODE_DEFAULT_ADAPTERS:
30
+ NodeAdapterRegistry.register(i)
31
+
16
32
  __all__ = ("Node",)
17
33
 
18
34
 
@@ -2,7 +2,6 @@
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
5
- from ._adapter import Adapter, AdapterRegistry
6
5
  from ._concepts import (
7
6
  Collective,
8
7
  Communicatable,
@@ -14,6 +13,7 @@ from ._concepts import (
14
13
  Relational,
15
14
  Sendable,
16
15
  )
16
+ from .adapters.adapter import Adapter, AdapterRegistry
17
17
  from .generic.element import ID, Element, IDError, IDType, validate_order
18
18
  from .generic.event import Event, EventStatus, Execution
19
19
  from .generic.log import Log, LogManager, LogManagerConfig
@@ -89,8 +89,8 @@ __all__ = (
89
89
  "MessageField",
90
90
  "MESSAGE_FIELDS",
91
91
  "validate_sender_recipient",
92
- "Adapter",
93
- "AdapterRegistry",
94
92
  "MessageManager",
95
93
  "to_list_type",
94
+ "Adapter",
95
+ "AdapterRegistry",
96
96
  )
@@ -1,14 +1 @@
1
- # Copyright (c) 2023 - 2024, HaiyangLi <quantocean.li at gmail dot com>
2
- #
3
- # SPDX-License-Identifier: Apache-2.0
4
-
5
- from .endpoints.base import APICalling, EndPoint
6
- from .imodel import iModel
7
- from .manager import iModelManager
8
-
9
- __all__ = (
10
- "iModel",
11
- "iModelManager",
12
- "EndPoint",
13
- "APICalling",
14
- )
1
+ from .types import *
@@ -12,7 +12,7 @@ from aiocache import cached
12
12
  from pydantic import BaseModel, ConfigDict, Field
13
13
 
14
14
  from lionagi._errors import ExecutionError, RateLimitError
15
- from lionagi.protocols.types import Event, EventStatus
15
+ from lionagi.protocols.generic.event import Event, EventStatus
16
16
  from lionagi.settings import Settings
17
17
 
18
18
  from .token_calculator import TokenCalculator
@@ -8,7 +8,8 @@ from typing import Self
8
8
 
9
9
  from typing_extensions import override
10
10
 
11
- from ...protocols.types import Executor, Processor
11
+ from lionagi.protocols.generic.processor import Executor, Processor
12
+
12
13
  from .base import APICalling
13
14
 
14
15
  __all__ = (
@@ -2,9 +2,9 @@
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
5
+ from lionagi.protocols._concepts import Manager
5
6
  from lionagi.utils import is_same_dtype
6
7
 
7
- from ..protocols._concepts import Manager
8
8
  from .endpoints.chat_completion import ChatCompletionEndPoint
9
9
  from .imodel import iModel
10
10
 
@@ -0,0 +1,18 @@
1
+ # Copyright (c) 2023 - 2024, HaiyangLi <quantocean.li at gmail dot com>
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ from .endpoints.base import APICalling, EndPoint
6
+ from .endpoints.rate_limited_processor import RateLimitedAPIExecutor
7
+ from .endpoints.token_calculator import TokenCalculator
8
+ from .imodel import iModel
9
+ from .manager import iModelManager
10
+
11
+ __all__ = (
12
+ "APICalling",
13
+ "EndPoint",
14
+ "RateLimitedAPIExecutor",
15
+ "TokenCalculator",
16
+ "iModel",
17
+ "iModelManager",
18
+ )
lionagi/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.6.0"
1
+ __version__ = "0.6.1"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lionagi
3
- Version: 0.6.0
3
+ Version: 0.6.1
4
4
  Summary: An AGentic Intelligence Operating System.
5
5
  Author-email: HaiyangLi <quantocean.li@gmail.com>
6
6
  License: Apache License
@@ -217,13 +217,13 @@ Classifier: Programming Language :: Python :: 3 :: Only
217
217
  Classifier: Programming Language :: Python :: 3.11
218
218
  Classifier: Programming Language :: Python :: 3.12
219
219
  Classifier: Programming Language :: Python :: 3.13
220
- Requires-Python: >=3.11
220
+ Requires-Python: >=3.10
221
221
  Requires-Dist: aiocache>=0.12.0
222
222
  Requires-Dist: aiohttp>=3.11.0
223
223
  Requires-Dist: jinja2>=3.1.0
224
224
  Requires-Dist: litellm>=1.55.3
225
225
  Requires-Dist: pandas>=2.0.0
226
- Requires-Dist: pillow>=11.0.0
226
+ Requires-Dist: pillow>=10.0.0
227
227
  Requires-Dist: pydantic>=2.0.0
228
228
  Requires-Dist: python-dotenv>=1.0.1
229
229
  Description-Content-Type: text/markdown
@@ -232,7 +232,7 @@ Description-Content-Type: text/markdown
232
232
  ![PyPI - Downloads](https://img.shields.io/pypi/dm/lionagi?color=blue)
233
233
  ![Python Version](https://img.shields.io/badge/python-3.10%2B-blue)
234
234
 
235
- [Documentation](https://ocean-lion.com/Welcome) | [Discord](https://discord.gg/aqSJ2v46vu) | [PyPI](https://pypi.org/project/lionagi/) | [Roadmap](https://trello.com/b/3seomsrI/lionagi)
235
+ [Documentation](https://lion-agi.github.io/lionagi/) | [Discord](https://discord.gg/aqSJ2v46vu) | [PyPI](https://pypi.org/project/lionagi/) | [Roadmap](https://trello.com/b/3seomsrI/lionagi)
236
236
 
237
237
  # LION Framework
238
238
  ### Language InterOperable Network - The Future of Controlled AI Operations
@@ -1,9 +1,9 @@
1
- lionagi/__init__.py,sha256=l4FOohHV6hKyCsbrbUabbXbu-yHSGNO_0wmRSPT_QT4,488
1
+ lionagi/__init__.py,sha256=sBS47lQGuXNAdfSoVLW8szKbCfDWrfAceMMUVYNK3IU,541
2
2
  lionagi/_class_registry.py,sha256=dutMsw-FQNqVV5gGH-NEIv90uBkSr8fERJ_x3swbb-s,3112
3
3
  lionagi/_errors.py,sha256=wNKdnVQvE_CHEstK7htrrj334RA_vbGcIds-3pUiRkc,455
4
4
  lionagi/settings.py,sha256=k9zRJXv57TveyfHO3Vr9VGiKrSwlRUUVKt5zf6v9RU4,1627
5
5
  lionagi/utils.py,sha256=hBlGmi8Px_ng3v4_D_k8xNpW3X93u01930lkZIHUQ-Y,73019
6
- lionagi/version.py,sha256=cID1jLnC_vj48GgMN6Yb1FA3JsQ95zNmCHmRYE8TFhY,22
6
+ lionagi/version.py,sha256=baAcEjLSYFIeNZF51tOMmA_zAMhN8HvKael-UU-Ruec,22
7
7
  lionagi/libs/__init__.py,sha256=v8vNyJVIVj8_Oz9RJdVe6ZKUQMYTgDh1VQpnr1KdLaw,112
8
8
  lionagi/libs/parse.py,sha256=tpEbmIRGuHhLCJlUlm6fjmqm_Z6XJLAXGNFHNuk422I,1011
9
9
  lionagi/libs/compress/__init__.py,sha256=v8vNyJVIVj8_Oz9RJdVe6ZKUQMYTgDh1VQpnr1KdLaw,112
@@ -43,24 +43,24 @@ lionagi/libs/validate/fuzzy_validate_mapping.py,sha256=SQqyxgrAgJ5zBKxIAnulWsZXb
43
43
  lionagi/libs/validate/string_similarity.py,sha256=7x8D4LZCMNJGz2ZCeKmct7Nc4i8m_ORoHIeGvkeMZOA,8733
44
44
  lionagi/libs/validate/validate_boolean.py,sha256=h3d7Dn7asJokBozWaKxaV_3Y6vUWBc0-zfNJjTQ9Bo8,3614
45
45
  lionagi/operations/__init__.py,sha256=_TvmWRotAQILyE3JWls7uY1luV7GAwwddtVdKnvjgIk,280
46
- lionagi/operations/types.py,sha256=_1HkP-xiWxh7l5dmqCnC_H40Unx_Nj11O1n9a1_WD80,181
46
+ lionagi/operations/types.py,sha256=_TvmWRotAQILyE3JWls7uY1luV7GAwwddtVdKnvjgIk,280
47
47
  lionagi/operations/utils.py,sha256=Twy6L_UFt9JqJFRYuKKTKVZIXsePidNl5ipcYcCbesI,1220
48
48
  lionagi/operations/brainstorm/__init__.py,sha256=v8vNyJVIVj8_Oz9RJdVe6ZKUQMYTgDh1VQpnr1KdLaw,112
49
49
  lionagi/operations/brainstorm/brainstorm.py,sha256=88Cq2IBrUs5du9q_8rf_VmhLYBfGKJv4rCeDTcJ07_g,17196
50
50
  lionagi/operations/brainstorm/prompt.py,sha256=f-Eh6pO606dT2TrX9BFv_einRDpYwFi6Gep9Strd1cM,610
51
51
  lionagi/operations/plan/__init__.py,sha256=AFkAmOJBTqPlYuqFRRn7rCvIw3CGh9XXH_22cNWbfig,156
52
- lionagi/operations/plan/plan.py,sha256=4DFBY6XSbTle96qCfx2QyN3ekTyZjrMar14eAl1zlAg,15327
52
+ lionagi/operations/plan/plan.py,sha256=Uxysob3evbjhXWS_wseO3Mb_A90p1wk3ralJ17rHFCk,15333
53
53
  lionagi/operations/plan/prompt.py,sha256=ig4JjJR5gV-lXPRVbiaJuL9qeoahM_afYvWphpY1lWA,993
54
54
  lionagi/operations/select/__init__.py,sha256=an28I5IbKj0waICk5SjYnz3WmkQLpIARO0yNUu9VWNE,162
55
55
  lionagi/operations/select/prompt.py,sha256=2OJQE8EKPj9nubP_drp6BYyF7J8RiDs1BEkv0D-HLn8,299
56
- lionagi/operations/select/select.py,sha256=NYHfrLUOLklVuvKCObHlmSj42R7ye8ftNS70vPPnOrQ,3151
56
+ lionagi/operations/select/select.py,sha256=B_XZcdmW9mmVGFZGnfCn89TxZvAMlS27YcD9RQ96f40,3166
57
57
  lionagi/operations/select/utils.py,sha256=hYOSGx7vMvjGHibcFOUuCfTXFO2IzzIUwQy82PQtluQ,3251
58
58
  lionagi/operations/strategies/__init__.py,sha256=v8vNyJVIVj8_Oz9RJdVe6ZKUQMYTgDh1VQpnr1KdLaw,112
59
59
  lionagi/operations/strategies/base.py,sha256=cfZXUZYPypW-hFZJj7HDtTPc-x99XB6dO_S5os1srTk,1820
60
60
  lionagi/operations/strategies/concurrent.py,sha256=bLLL90LYywkxGlMY8XXGsZ1GRZrtB_8lsfkqspLgQ6o,2721
61
61
  lionagi/operations/strategies/concurrent_chunk.py,sha256=9qwYoqO0LO1BMIyxU-tc_9ppBK0J94cnWs3e7wx7PR0,1678
62
62
  lionagi/operations/strategies/concurrent_sequential_chunk.py,sha256=5Zw9fO1YWSj81w6IjOdEPzHE-4TxIdui-ljjrAsbEEI,3658
63
- lionagi/operations/strategies/params.py,sha256=BMGclThbRYnUmmcFSh9JAng12dykBl_Ud_5VHLp18g0,4966
63
+ lionagi/operations/strategies/params.py,sha256=XNCD8sQJCm7xk0yGFKSQ14FuUNV1f8wLfNNJg_NYsn8,5407
64
64
  lionagi/operations/strategies/sequential.py,sha256=nSMtYy10P4W8U2SoARfKCBDN6y8_WoubKjoORUnewjY,949
65
65
  lionagi/operations/strategies/sequential_chunk.py,sha256=bs_0zZJjJpYdmEEWx3mwh3it5ErQYfZr-ImahyKEy8Y,3161
66
66
  lionagi/operations/strategies/sequential_concurrent_chunk.py,sha256=GJurnTuu6U7FOPR9mZxkjoJMIiQbgvRGt5iZZtmB2mY,3559
@@ -71,10 +71,10 @@ lionagi/operatives/operative.py,sha256=WZeg1XHS8iuzs4I3-va9FS9tOWu0XZ7xnOVzHthvE
71
71
  lionagi/operatives/step.py,sha256=DevwisZc2q88ynUiiSu7VBEY2A_G4Q5iRLrVgVLHNJU,9843
72
72
  lionagi/operatives/types.py,sha256=8krpGIeJL2GkO580ePOuAZfGc7vUVPIanemoA77tbVY,1697
73
73
  lionagi/operatives/action/__init__.py,sha256=v8vNyJVIVj8_Oz9RJdVe6ZKUQMYTgDh1VQpnr1KdLaw,112
74
- lionagi/operatives/action/function_calling.py,sha256=d07l39EqIsLOvWUcxWo1UjWu8VDfbjhGKJVA_In8tjs,4594
75
- lionagi/operatives/action/manager.py,sha256=XFFl93xaeErX4lZz6060nscsG4OnYPz7eM4WoJ14n4g,7813
74
+ lionagi/operatives/action/function_calling.py,sha256=VHUq8qebCAAdaWcPJQCZNI-P6zC_P1kp9o-d7nhZf_0,4602
75
+ lionagi/operatives/action/manager.py,sha256=H50L9fv6kpQ87vW4nEIfP1JHZ5gX4fQs0uPDeRpEYEw,7929
76
76
  lionagi/operatives/action/request_response_model.py,sha256=7X_ZkcgmQ0D77qyP8_39RdEAKASCjEPWH4ey83jIUKc,2326
77
- lionagi/operatives/action/tool.py,sha256=Wxmh5v0pH4qjYGXn7w-RCGh756ARhgGfq7mjcn2EIic,4267
77
+ lionagi/operatives/action/tool.py,sha256=fUwlzmi6kuuwHU6xA8Soo_bWOgD-I7TBLtJ-WJ1OBLk,4277
78
78
  lionagi/operatives/action/utils.py,sha256=vUe7Aysuzbg16rAfe2Ttp5QUz5_L6mMedBVAWzGAHwk,4330
79
79
  lionagi/operatives/forms/__init__.py,sha256=v8vNyJVIVj8_Oz9RJdVe6ZKUQMYTgDh1VQpnr1KdLaw,112
80
80
  lionagi/operatives/forms/base.py,sha256=ALPREgOkRcY2wtRG0JpTXztlohkRjyCiwoleQfGCpSg,7207
@@ -95,20 +95,28 @@ lionagi/operatives/models/note.py,sha256=8TS0Zi0eSo1fmVoqBMWB6ChSrXKb36ozAM70o7P
95
95
  lionagi/operatives/models/operable_model.py,sha256=mnTIAXJHJecXjqKNZWSch5w6x3U3Fl_9mUK4RudnM64,15573
96
96
  lionagi/operatives/models/schema_model.py,sha256=-BeCwW_1Rle--w-f7MajbOYH7t_8SPWw0_qK0fpTsRg,666
97
97
  lionagi/protocols/__init__.py,sha256=v8vNyJVIVj8_Oz9RJdVe6ZKUQMYTgDh1VQpnr1KdLaw,112
98
- lionagi/protocols/_adapter.py,sha256=UPz6LlEb1fAc53Cq8QJLpVngFlPqi2JnMUqqi2FxkPM,5875
99
98
  lionagi/protocols/_concepts.py,sha256=aIV3cIuKxRcEFdROemlFR6mMAwqiYv-rjkZQ4rHBfXo,1554
100
- lionagi/protocols/types.py,sha256=of761-J1RDZEZXIPxEXVz2PRg_KuajfMrjzhZGwk2o4,2057
99
+ lionagi/protocols/types.py,sha256=M-cWgRGl8vaU776MuX-QSQVmaI1rbXmzyW9tfPHzGYc,2065
100
+ lionagi/protocols/adapters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
101
+ lionagi/protocols/adapters/adapter.py,sha256=CyAZ4IR6S4FSmKMk_3YzyE1Ny8TJjeYc4h1Z710WL6M,2417
102
+ lionagi/protocols/adapters/json_adapter.py,sha256=Jl0pyu2r-vZ5PVfqBzp3eAl9no9MQwg2ln5ty3UDI4s,2337
103
+ lionagi/protocols/adapters/types.py,sha256=qYCbxjWNLVIUOosC3N8oJHP8tDJ9kjsnaYuUh_h-70c,563
104
+ lionagi/protocols/adapters/pandas_/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
105
+ lionagi/protocols/adapters/pandas_/csv_adapter.py,sha256=iKBX1XXRh85O4595pvxKwxv5A-80OYBhzQoaAeF6MgI,1307
106
+ lionagi/protocols/adapters/pandas_/excel_adapter.py,sha256=XoPD16Kus6lPNUEsy8JZDi5JMlwSsB6VVOQU3QIOoIs,1356
107
+ lionagi/protocols/adapters/pandas_/pd_dataframe_adapter.py,sha256=3JQFTN7xTovPet98cOxx2mCq1O7OXZnXZEZv6m06dtc,908
108
+ lionagi/protocols/adapters/pandas_/pd_series_adapter.py,sha256=f5mj4HSL6G1R02RaRRxQ06bfxble19da8BtH3WD889M,434
101
109
  lionagi/protocols/generic/__init__.py,sha256=v8vNyJVIVj8_Oz9RJdVe6ZKUQMYTgDh1VQpnr1KdLaw,112
102
110
  lionagi/protocols/generic/element.py,sha256=Pi-YHinDDab7sIYNo4Caj-gJGBidcIAEN1Bpl1D100Q,14161
103
111
  lionagi/protocols/generic/event.py,sha256=SjR9N4Egr5_oqOBSKVsxQjsn6MlqNcwf48bee-qIT6Y,4879
104
112
  lionagi/protocols/generic/log.py,sha256=xi8dRKwxtxVYU8T_E4wYJE4lCQzkERgAUARcAN7ZngI,7441
105
- lionagi/protocols/generic/pile.py,sha256=TpPZVqlc09-mTdMuEUKfG8znqO9U7ahWi-wsP6tMP-s,30999
113
+ lionagi/protocols/generic/pile.py,sha256=kXzN9ZHmmR__tOItwvx9xcB9IDxJYYHIkHOtDX0wsFE,31509
106
114
  lionagi/protocols/generic/processor.py,sha256=4Gkie1DxE0U-uZAdNBTuTibUlyeEGm_OyVlMXilCEm8,10115
107
115
  lionagi/protocols/generic/progression.py,sha256=3PjIBlPoj7jahy75ERbo9vHKVNU7fFl4be5ETNzphJU,15160
108
116
  lionagi/protocols/graph/__init__.py,sha256=v8vNyJVIVj8_Oz9RJdVe6ZKUQMYTgDh1VQpnr1KdLaw,112
109
117
  lionagi/protocols/graph/edge.py,sha256=LOESNQc3aVNKXZrr5ZrRCK5biTWkyxGtTQ7GxJFyCx8,5221
110
118
  lionagi/protocols/graph/graph.py,sha256=bRlZot_6eN4K3CYxgFnfehnQHDGJTQ3OPqITaz8ETiU,10055
111
- lionagi/protocols/graph/node.py,sha256=s9TmFIXY2yL9Vc8nlzTfaM9ZXP8qboqcF5pvfgG0HA0,3435
119
+ lionagi/protocols/graph/node.py,sha256=5VStUHSV0Qjv6DtwJPCzod2stveixnsErJR09uLLYhc,3773
112
120
  lionagi/protocols/mail/__init__.py,sha256=v8vNyJVIVj8_Oz9RJdVe6ZKUQMYTgDh1VQpnr1KdLaw,112
113
121
  lionagi/protocols/mail/exchange.py,sha256=bT-JUU9CXDdUn6GlAjB1Pc4KD7J8Ncm7s-xbmFKI45g,4066
114
122
  lionagi/protocols/mail/mail.py,sha256=4O4R0ak7dFar80wjj1DK64SPgRhYAR7qKjv_tSDbkXA,625
@@ -131,14 +139,15 @@ lionagi/protocols/messages/templates/assistant_response.jinja2,sha256=oKOX4myBy7
131
139
  lionagi/protocols/messages/templates/instruction_message.jinja2,sha256=L-ptw5OHxdL1KVKVhLOn0KAFw6IEFI9QHZxiFuovzhk,1382
132
140
  lionagi/protocols/messages/templates/system_message.jinja2,sha256=JRKJ0aFpYfaXSFouKc_N4unZ35C3yZTOWhIrIdCB5qk,215
133
141
  lionagi/protocols/messages/templates/tool_schemas.jinja2,sha256=ozIaSDCRjIAhLyA8VM6S-YqS0w2NcctALSwx4LjDwII,126
134
- lionagi/service/__init__.py,sha256=1v6f3RxLaZmSRj3uCEahSg0plWsxV8l_UisLbUOXoAQ,308
142
+ lionagi/service/__init__.py,sha256=DMGXIqPsmut9H5GT0ZeSzQIzYzzPwI-2gLXydpbwiV8,21
135
143
  lionagi/service/imodel.py,sha256=-FudX8C_wmc7ByUv-pILrybtQd4E2gfE51C5l0IR0ho,10815
136
- lionagi/service/manager.py,sha256=qM_URzibfWvtqcunTJ0jwrAPR9X3R4XomSecKseAD_4,1429
144
+ lionagi/service/manager.py,sha256=MKSYBkg23s7YhZy5GEFdnpspEnhPVfFhpkpoJe20D7k,1435
145
+ lionagi/service/types.py,sha256=v9SAn5-GTmds4Mar13Or_VFrRHCinBK99dmeDUd-QNk,486
137
146
  lionagi/service/endpoints/__init__.py,sha256=v8vNyJVIVj8_Oz9RJdVe6ZKUQMYTgDh1VQpnr1KdLaw,112
138
- lionagi/service/endpoints/base.py,sha256=K6VM4wn4Lk59tzdbsC_Q263lmKMqJFJNbrJ0wKQrH1g,18267
147
+ lionagi/service/endpoints/base.py,sha256=RbBBQIbtNtkP1LT9U3ZrhL35SfmVIpaq-AGW8d538k4,18275
139
148
  lionagi/service/endpoints/chat_completion.py,sha256=9ltSQaKPH43WdEDW32_-f5x07I9hOU8g-T_PAG-nYsQ,2529
140
149
  lionagi/service/endpoints/match_endpoint.py,sha256=n7F9NoTXfUBL29HrDcFLF5AXYR8pcx_IumQ7BiJXC-w,1740
141
- lionagi/service/endpoints/rate_limited_processor.py,sha256=mBSf4d58Dss45NMam6r8nvwxjUKw6CjXcq7IpUqkDV8,4663
150
+ lionagi/service/endpoints/rate_limited_processor.py,sha256=GkWK9XR3XNwn6qKUif6HMeqMJtO1E2Hq_tqGYai_wp8,4681
142
151
  lionagi/service/endpoints/token_calculator.py,sha256=MflqImGUr_1jh465hB7cUAaIPICBkjirvre1fWGXLrA,6161
143
152
  lionagi/service/providers/__init__.py,sha256=v8vNyJVIVj8_Oz9RJdVe6ZKUQMYTgDh1VQpnr1KdLaw,112
144
153
  lionagi/service/providers/anthropic_/__init__.py,sha256=v8vNyJVIVj8_Oz9RJdVe6ZKUQMYTgDh1VQpnr1KdLaw,112
@@ -154,7 +163,7 @@ lionagi/service/providers/perplexity_/chat_completions.py,sha256=SsDbrtXwQsR4Yu2
154
163
  lionagi/session/__init__.py,sha256=v8vNyJVIVj8_Oz9RJdVe6ZKUQMYTgDh1VQpnr1KdLaw,112
155
164
  lionagi/session/branch.py,sha256=-lu63-Eua1pgo9RVoiS54G4_JtmNC__ZEaegRtKFPro,47448
156
165
  lionagi/session/session.py,sha256=A2PCG1BD1noMLtCJD3C_H7r-0GUQ_ru2szOhF1pOCtY,8976
157
- lionagi-0.6.0.dist-info/METADATA,sha256=THShEYoEI8tUGFhUjDZXSqF6esJrx86Alx2cCSu2-5M,22771
158
- lionagi-0.6.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
159
- lionagi-0.6.0.dist-info/licenses/LICENSE,sha256=VXFWsdoN5AAknBCgFqQNgPWYx7OPp-PFEP961zGdOjc,11288
160
- lionagi-0.6.0.dist-info/RECORD,,
166
+ lionagi-0.6.1.dist-info/METADATA,sha256=_KZh-djuuzJ-mwnUvpVUJ7TGmw_ghQnj0_QvqG8nkFY,22776
167
+ lionagi-0.6.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
168
+ lionagi-0.6.1.dist-info/licenses/LICENSE,sha256=VXFWsdoN5AAknBCgFqQNgPWYx7OPp-PFEP961zGdOjc,11288
169
+ lionagi-0.6.1.dist-info/RECORD,,
@@ -1,224 +0,0 @@
1
- # Copyright (c) 2023 - 2024, HaiyangLi <quantocean.li at gmail dot com>
2
- #
3
- # SPDX-License-Identifier: Apache-2.0
4
-
5
- import json
6
- import logging
7
- from datetime import datetime
8
- from pathlib import Path
9
- from typing import Any, Protocol, TypeVar, runtime_checkable
10
-
11
- import pandas as pd
12
- from typing_extensions import get_protocol_members
13
-
14
- T = TypeVar("T")
15
-
16
-
17
- @runtime_checkable
18
- class Adapter(Protocol):
19
-
20
- obj_key: str
21
-
22
- @classmethod
23
- def from_obj(
24
- cls, subj_cls: type[T], obj: Any, /, **kwargs
25
- ) -> dict | list[dict]: ...
26
-
27
- @classmethod
28
- def to_obj(cls, subj: T, /, **kwargs) -> Any: ...
29
-
30
-
31
- adapter_members = get_protocol_members(Adapter) # duck typing
32
-
33
-
34
- class AdapterRegistry:
35
-
36
- _adapters: dict[str, Adapter] = {}
37
-
38
- @classmethod
39
- def list_adapters(cls) -> list[tuple[str | type, ...]]:
40
- return list(cls._adapters.keys())
41
-
42
- @classmethod
43
- def register(cls, adapter: type[Adapter]) -> None:
44
- for member in adapter_members:
45
- if not hasattr(adapter, member):
46
- _str = getattr(adapter, "obj_key", None) or repr(adapter)
47
- _str = _str[:50] if len(_str) > 50 else _str
48
- raise AttributeError(
49
- f"Adapter {_str} missing required methods."
50
- )
51
-
52
- if isinstance(adapter, type):
53
- cls._adapters[adapter.obj_key] = adapter()
54
- else:
55
- cls._adapters[adapter.obj_key] = adapter
56
-
57
- @classmethod
58
- def get(cls, obj_key: type | str) -> Adapter:
59
- try:
60
- return cls._adapters[obj_key]
61
- except Exception as e:
62
- logging.error(f"Error getting adapter for {obj_key}. Error: {e}")
63
-
64
- @classmethod
65
- def adapt_from(
66
- cls, subj_cls: type[T], obj: Any, obj_key: type | str, **kwargs
67
- ) -> dict | list[dict]:
68
- try:
69
- return cls.get(obj_key).from_obj(subj_cls, obj, **kwargs)
70
- except Exception as e:
71
- logging.error(f"Error adapting data from {obj_key}. Error: {e}")
72
- raise e
73
-
74
- @classmethod
75
- def adapt_to(cls, subj: T, obj_key: type | str, **kwargs) -> Any:
76
- try:
77
- return cls.get(obj_key).to_obj(subj, **kwargs)
78
- except Exception as e:
79
- logging.error(f"Error adapting data to {obj_key}. Error: {e}")
80
- raise e
81
-
82
-
83
- class JsonAdapter(Adapter):
84
-
85
- obj_key = "json"
86
-
87
- @classmethod
88
- def from_obj(cls, subj_cls: type[T], obj: str, /) -> dict:
89
- return json.loads(obj)
90
-
91
- @classmethod
92
- def to_obj(cls, subj: T) -> str:
93
- return json.dumps(subj.to_dict())
94
-
95
-
96
- class JsonFileAdapter(Adapter):
97
-
98
- obj_key = ".json"
99
-
100
- @classmethod
101
- def from_obj(cls, subj_cls: type[T], obj: str | Path, /) -> dict:
102
- with open(obj) as f:
103
- return json.load(f)
104
-
105
- @classmethod
106
- def to_obj(
107
- cls,
108
- subj: T,
109
- /,
110
- fp: str | Path,
111
- ) -> None:
112
- with open(fp, "w") as f:
113
- json.dump(subj.to_dict(), f)
114
- logging.info(f"Successfully saved data to {fp}")
115
-
116
-
117
- class PandasSeriesAdapter(Adapter):
118
-
119
- obj_key = "pd_series"
120
- alias = ("pandas_series", "pd.series", "pd_series")
121
-
122
- @classmethod
123
- def from_obj(cls, subj_cls: type[T], obj: pd.Series, /, **kwargs) -> dict:
124
- return obj.to_dict(**kwargs)
125
-
126
- @classmethod
127
- def to_obj(cls, subj: T, /, **kwargs) -> pd.Series:
128
- return pd.Series(subj.to_dict(), **kwargs)
129
-
130
-
131
- class PandasDataFrameAdapter(Adapter):
132
-
133
- obj_key = "pd_dataframe"
134
- alias = ("pandas_dataframe", "pd.DataFrame", "pd_dataframe")
135
-
136
- @classmethod
137
- def from_obj(
138
- cls, subj_cls: type[T], obj: pd.DataFrame, /, **kwargs
139
- ) -> list[dict]:
140
- """kwargs for pd.DataFrame.to_dict"""
141
- return obj.to_dict(orient="records", **kwargs)
142
-
143
- @classmethod
144
- def to_obj(cls, subj: list[T], /, **kwargs) -> pd.DataFrame:
145
- """kwargs for pd.DataFrame"""
146
- out_ = []
147
- for i in subj:
148
- _dict = i.to_dict()
149
- _dict["created_at"] = datetime.fromtimestamp(_dict["created_at"])
150
- out_.append(_dict)
151
- df = pd.DataFrame(out_, **kwargs)
152
- if "created_at" in df.columns:
153
- df["created_at"] = pd.to_datetime(df["created_at"])
154
- return df
155
-
156
-
157
- class CSVFileAdapter(Adapter):
158
-
159
- obj_key = ".csv"
160
- alias = (".csv", "csv_file", "csv")
161
-
162
- @classmethod
163
- def from_obj(
164
- cls, subj_cls: type[T], obj: str | Path, /, **kwargs
165
- ) -> list[dict]:
166
- """kwargs for pd.read_csv"""
167
- df = pd.read_csv(obj, **kwargs)
168
- return df.to_dict(orient="records")
169
-
170
- @classmethod
171
- def to_obj(
172
- cls,
173
- subj: list[T],
174
- /,
175
- fp: str | Path,
176
- **kwargs,
177
- ) -> None:
178
- """kwargs for pd.DataFrame.to_csv"""
179
- kwargs["index"] = False
180
- pd.DataFrame([i.to_dict() for i in subj]).to_csv(fp, **kwargs)
181
- logging.info(f"Successfully saved data to {fp}")
182
-
183
-
184
- class ExcelFileAdapter(Adapter):
185
-
186
- obj_key = ".xlsx"
187
- alias = (".xlsx", "excel_file", "excel", "xlsx", "xls", ".xls")
188
-
189
- @classmethod
190
- def from_obj(
191
- cls, subj_cls: type[T], obj: str | Path, /, **kwargs
192
- ) -> list[dict]:
193
- return pd.read_excel(obj, **kwargs).to_dict(orient="records")
194
-
195
- @classmethod
196
- def to_obj(cls, subj: list[T], /, fp: str | Path, **kwargs) -> None:
197
- kwargs["index"] = False
198
- pd.DataFrame([i.to_dict() for i in subj]).to_excel(fp, **kwargs)
199
- logging.info(f"Saved {subj.class_name()} to {fp}")
200
-
201
-
202
- NODE_ADAPTERS = [
203
- JsonAdapter,
204
- JsonFileAdapter,
205
- PandasSeriesAdapter,
206
- ]
207
-
208
-
209
- class NodeAdapterRegistry(AdapterRegistry):
210
- _adapters = {k.obj_key: k() for k in NODE_ADAPTERS}
211
-
212
-
213
- PILE_ADAPTERS = [
214
- JsonAdapter,
215
- JsonFileAdapter,
216
- PandasDataFrameAdapter,
217
- CSVFileAdapter,
218
- ExcelFileAdapter,
219
- ]
220
-
221
-
222
- class PileAdapterRegistry(AdapterRegistry):
223
-
224
- _adapters = {k.obj_key: k() for k in PILE_ADAPTERS}