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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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}