graphrag_sdk 0.8.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.
- graphrag_sdk/__init__.py +40 -0
- graphrag_sdk/agents/__init__.py +3 -0
- graphrag_sdk/agents/agent.py +165 -0
- graphrag_sdk/agents/kg_agent.py +148 -0
- graphrag_sdk/attribute.py +170 -0
- graphrag_sdk/chat_session.py +211 -0
- graphrag_sdk/document.py +24 -0
- graphrag_sdk/document_loaders/__init__.py +17 -0
- graphrag_sdk/document_loaders/csv.py +33 -0
- graphrag_sdk/document_loaders/html.py +50 -0
- graphrag_sdk/document_loaders/jsonl.py +28 -0
- graphrag_sdk/document_loaders/pdf.py +40 -0
- graphrag_sdk/document_loaders/string.py +25 -0
- graphrag_sdk/document_loaders/text.py +31 -0
- graphrag_sdk/document_loaders/url.py +50 -0
- graphrag_sdk/entity.py +161 -0
- graphrag_sdk/fixtures/prompts.py +617 -0
- graphrag_sdk/fixtures/regex.py +7 -0
- graphrag_sdk/graph_metrics.py +635 -0
- graphrag_sdk/helpers.py +315 -0
- graphrag_sdk/kg.py +410 -0
- graphrag_sdk/model_config.py +101 -0
- graphrag_sdk/models/__init__.py +16 -0
- graphrag_sdk/models/azure_openai.py +115 -0
- graphrag_sdk/models/gemini.py +111 -0
- graphrag_sdk/models/litellm.py +278 -0
- graphrag_sdk/models/model.py +126 -0
- graphrag_sdk/models/ollama.py +139 -0
- graphrag_sdk/models/openai.py +110 -0
- graphrag_sdk/ontology.py +452 -0
- graphrag_sdk/orchestrator/__init__.py +10 -0
- graphrag_sdk/orchestrator/execution_plan.py +45 -0
- graphrag_sdk/orchestrator/orchestrator.py +114 -0
- graphrag_sdk/orchestrator/orchestrator_decision.py +91 -0
- graphrag_sdk/orchestrator/orchestrator_runner.py +332 -0
- graphrag_sdk/orchestrator/step.py +92 -0
- graphrag_sdk/orchestrator/step_result.py +25 -0
- graphrag_sdk/orchestrator/steps/__init__.py +21 -0
- graphrag_sdk/orchestrator/steps/agent.py +202 -0
- graphrag_sdk/orchestrator/steps/parallel.py +198 -0
- graphrag_sdk/orchestrator/steps/summary.py +141 -0
- graphrag_sdk/orchestrator/steps/user_input.py +183 -0
- graphrag_sdk/rdf_extractor.py +301 -0
- graphrag_sdk/relation.py +258 -0
- graphrag_sdk/source.py +190 -0
- graphrag_sdk/steps/Step.py +4 -0
- graphrag_sdk/steps/create_ontology_step.py +311 -0
- graphrag_sdk/steps/extract_data_step.py +378 -0
- graphrag_sdk/steps/graph_query_step.py +103 -0
- graphrag_sdk/steps/qa_step.py +52 -0
- graphrag_sdk/steps/stream_qa_step.py +51 -0
- graphrag_sdk-0.8.1.dist-info/LICENSE +21 -0
- graphrag_sdk-0.8.1.dist-info/METADATA +411 -0
- graphrag_sdk-0.8.1.dist-info/RECORD +55 -0
- graphrag_sdk-0.8.1.dist-info/WHEEL +4 -0
graphrag_sdk/__init__.py
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
from .source import Source
|
|
2
|
+
from .ontology import Ontology
|
|
3
|
+
from .kg import KnowledgeGraph
|
|
4
|
+
from .model_config import KnowledgeGraphModelConfig
|
|
5
|
+
from .steps.create_ontology_step import CreateOntologyStep
|
|
6
|
+
from .models.model import (
|
|
7
|
+
GenerativeModel,
|
|
8
|
+
GenerationResponse,
|
|
9
|
+
GenerativeModelChatSession,
|
|
10
|
+
GenerativeModelConfig,
|
|
11
|
+
FinishReason,
|
|
12
|
+
)
|
|
13
|
+
from .entity import Entity
|
|
14
|
+
from .relation import Relation
|
|
15
|
+
from .attribute import Attribute, AttributeType
|
|
16
|
+
|
|
17
|
+
# Setup Null handler
|
|
18
|
+
import logging
|
|
19
|
+
|
|
20
|
+
logger = logging.getLogger(__name__)
|
|
21
|
+
logger.setLevel(logging.DEBUG)
|
|
22
|
+
logger.addHandler(logging.NullHandler())
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
__all__ = [
|
|
26
|
+
"Source",
|
|
27
|
+
"Ontology",
|
|
28
|
+
"KnowledgeGraph",
|
|
29
|
+
"KnowledgeGraphModelConfig",
|
|
30
|
+
"CreateOntologyStep",
|
|
31
|
+
"GenerativeModel",
|
|
32
|
+
"GenerationResponse",
|
|
33
|
+
"GenerativeModelChatSession",
|
|
34
|
+
"GenerativeModelConfig",
|
|
35
|
+
"FinishReason",
|
|
36
|
+
"Entity",
|
|
37
|
+
"Relation",
|
|
38
|
+
"Attribute",
|
|
39
|
+
"AttributeType",
|
|
40
|
+
]
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
|
|
3
|
+
class AgentResponseCode:
|
|
4
|
+
"""
|
|
5
|
+
Represents the response codes for an agent.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
AGENT_RESPONSE = "agent_response"
|
|
9
|
+
AGENT_ERROR = "agent_error"
|
|
10
|
+
AGENT_REQUEST_INPUT = "agent_request_input"
|
|
11
|
+
|
|
12
|
+
@staticmethod
|
|
13
|
+
def from_str(text: str) -> "AgentResponseCode":
|
|
14
|
+
"""
|
|
15
|
+
Converts a string to an AgentResponseCode object.
|
|
16
|
+
|
|
17
|
+
Args:
|
|
18
|
+
text (str): The string representation of the response code.
|
|
19
|
+
|
|
20
|
+
Returns:
|
|
21
|
+
AgentResponseCode: The corresponding AgentResponseCode object.
|
|
22
|
+
|
|
23
|
+
Raises:
|
|
24
|
+
ValueError: If the input string does not match any known response code.
|
|
25
|
+
"""
|
|
26
|
+
if text == AgentResponseCode.AGENT_RESPONSE:
|
|
27
|
+
return AgentResponseCode.AGENT_RESPONSE
|
|
28
|
+
elif text == AgentResponseCode.AGENT_ERROR:
|
|
29
|
+
return AgentResponseCode.AGENT_ERROR
|
|
30
|
+
elif text == AgentResponseCode.AGENT_REQUEST_INPUT:
|
|
31
|
+
return AgentResponseCode.AGENT_REQUEST_INPUT
|
|
32
|
+
else:
|
|
33
|
+
raise ValueError(f"Unknown agent response code: {text}")
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class AgentResponse:
|
|
37
|
+
"""
|
|
38
|
+
Represents a response from an agent.
|
|
39
|
+
|
|
40
|
+
Attributes:
|
|
41
|
+
response_code (AgentResponseCode): The response code.
|
|
42
|
+
payload (dict): The payload of the response.
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
def __init__(self, response_code: AgentResponseCode, payload: dict):
|
|
46
|
+
"""
|
|
47
|
+
Initializes a new Agent object.
|
|
48
|
+
|
|
49
|
+
Args:
|
|
50
|
+
response_code (AgentResponseCode): The response code of the agent.
|
|
51
|
+
payload (dict): The payload associated with the agent.
|
|
52
|
+
|
|
53
|
+
"""
|
|
54
|
+
self.response_code = response_code
|
|
55
|
+
self.payload = payload
|
|
56
|
+
|
|
57
|
+
def to_json(self) -> dict:
|
|
58
|
+
"""
|
|
59
|
+
Converts the AgentResponse object to a JSON-compatible dictionary.
|
|
60
|
+
|
|
61
|
+
Returns:
|
|
62
|
+
dict: The JSON representation of the AgentResponse object.
|
|
63
|
+
"""
|
|
64
|
+
return {
|
|
65
|
+
"response_code": self.response_code,
|
|
66
|
+
"payload": self.payload,
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
@staticmethod
|
|
70
|
+
def from_json(json: dict) -> "AgentResponse":
|
|
71
|
+
"""
|
|
72
|
+
Creates an AgentResponse object from a JSON-compatible dictionary.
|
|
73
|
+
|
|
74
|
+
Args:
|
|
75
|
+
json (dict): The JSON representation of the AgentResponse object.
|
|
76
|
+
|
|
77
|
+
Returns:
|
|
78
|
+
AgentResponse: The created AgentResponse object.
|
|
79
|
+
"""
|
|
80
|
+
return AgentResponse(
|
|
81
|
+
AgentResponseCode.from_str(json["response_code"]),
|
|
82
|
+
json["payload"],
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
def __str__(self) -> str:
|
|
86
|
+
"""
|
|
87
|
+
Returns a string representation of the AgentResponse object.
|
|
88
|
+
|
|
89
|
+
Returns:
|
|
90
|
+
str: The string representation of the AgentResponse object.
|
|
91
|
+
"""
|
|
92
|
+
return (
|
|
93
|
+
f"AgentResponse(response_code={self.response_code}, payload={self.payload})"
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
def __repr__(self) -> str:
|
|
97
|
+
"""
|
|
98
|
+
Returns a string representation of the AgentResponse object.
|
|
99
|
+
|
|
100
|
+
Returns:
|
|
101
|
+
str: The string representation of the AgentResponse object.
|
|
102
|
+
"""
|
|
103
|
+
return str(self)
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
class Agent(ABC):
|
|
107
|
+
"""
|
|
108
|
+
Abstract base class for agents in the system.
|
|
109
|
+
"""
|
|
110
|
+
|
|
111
|
+
@property
|
|
112
|
+
@abstractmethod
|
|
113
|
+
def agent_id(self) -> str:
|
|
114
|
+
"""
|
|
115
|
+
Get the unique identifier of the agent.
|
|
116
|
+
|
|
117
|
+
Returns:
|
|
118
|
+
str: The agent's identifier.
|
|
119
|
+
"""
|
|
120
|
+
pass
|
|
121
|
+
|
|
122
|
+
@property
|
|
123
|
+
@abstractmethod
|
|
124
|
+
def introduction(self) -> str:
|
|
125
|
+
"""
|
|
126
|
+
Get the introduction of the agent.
|
|
127
|
+
|
|
128
|
+
Returns:
|
|
129
|
+
str: The agent's introduction.
|
|
130
|
+
"""
|
|
131
|
+
pass
|
|
132
|
+
|
|
133
|
+
@property
|
|
134
|
+
@abstractmethod
|
|
135
|
+
def interface(self) -> list[dict]:
|
|
136
|
+
"""
|
|
137
|
+
Get the interface of the agent.
|
|
138
|
+
|
|
139
|
+
Returns:
|
|
140
|
+
List[Dict]: The agent's interface.
|
|
141
|
+
"""
|
|
142
|
+
pass
|
|
143
|
+
|
|
144
|
+
@abstractmethod
|
|
145
|
+
def run(self, params: dict) -> str:
|
|
146
|
+
"""
|
|
147
|
+
Run the agent with the given parameters and chat session.
|
|
148
|
+
|
|
149
|
+
Args:
|
|
150
|
+
params (Dict): The parameters for the agent.
|
|
151
|
+
|
|
152
|
+
Returns:
|
|
153
|
+
str: The agent's response.
|
|
154
|
+
"""
|
|
155
|
+
pass
|
|
156
|
+
|
|
157
|
+
@abstractmethod
|
|
158
|
+
def __repr__(self) -> str:
|
|
159
|
+
"""
|
|
160
|
+
Get a string representation of the agent.
|
|
161
|
+
|
|
162
|
+
Returns:
|
|
163
|
+
str: The string representation of the agent.
|
|
164
|
+
"""
|
|
165
|
+
pass
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
from .agent import Agent
|
|
2
|
+
from graphrag_sdk.kg import KnowledgeGraph
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class KGAgent(Agent):
|
|
6
|
+
"""Represents an Agent for a FalkorDB Knowledge Graph.
|
|
7
|
+
|
|
8
|
+
Args:
|
|
9
|
+
agent_id (str): The ID of the agent.
|
|
10
|
+
kg (KnowledgeGraph): The knowledge graph to query.
|
|
11
|
+
introduction (str): The introduction to the agent.
|
|
12
|
+
|
|
13
|
+
Examples:
|
|
14
|
+
>>> from graphrag_sdk import KnowledgeGraph, Orchestrator
|
|
15
|
+
>>> from graphrag_sdk.agents.kg_agent import KGAgent
|
|
16
|
+
>>> orchestrator = Orchestrator(model)
|
|
17
|
+
>>> kg = KnowledgeGraph("test_kg", ontology, model)
|
|
18
|
+
>>> agent = KGAgent("test_agent", kg, "This is a test agent.")
|
|
19
|
+
>>> orchestrator.register_agent(agent)
|
|
20
|
+
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
_interface = [
|
|
24
|
+
{
|
|
25
|
+
"name": "prompt",
|
|
26
|
+
"type": "string",
|
|
27
|
+
"required": True,
|
|
28
|
+
"description": "The prompt to ask the agent.",
|
|
29
|
+
}
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
def __init__(self, agent_id: str, kg: KnowledgeGraph, introduction: str):
|
|
33
|
+
"""
|
|
34
|
+
Initializes a KGAgent object.
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
agent_id (str): The ID of the agent.
|
|
38
|
+
kg (KnowledgeGraph): The knowledge graph associated with the agent.
|
|
39
|
+
introduction (str): The introduction of the agent.
|
|
40
|
+
"""
|
|
41
|
+
super().__init__()
|
|
42
|
+
self.agent_id = agent_id
|
|
43
|
+
self.introduction = introduction
|
|
44
|
+
self.kg = kg
|
|
45
|
+
self.chat_session = self._kg.chat_session()
|
|
46
|
+
|
|
47
|
+
@property
|
|
48
|
+
def agent_id(self) -> str:
|
|
49
|
+
"""
|
|
50
|
+
Returns the ID of the agent.
|
|
51
|
+
|
|
52
|
+
Returns:
|
|
53
|
+
str: The ID of the agent.
|
|
54
|
+
"""
|
|
55
|
+
return self._agent_id
|
|
56
|
+
|
|
57
|
+
@agent_id.setter
|
|
58
|
+
def agent_id(self, value) -> None:
|
|
59
|
+
"""
|
|
60
|
+
Sets the agent ID.
|
|
61
|
+
|
|
62
|
+
Args:
|
|
63
|
+
value (str): The ID of the agent.
|
|
64
|
+
"""
|
|
65
|
+
self._agent_id = value
|
|
66
|
+
|
|
67
|
+
@property
|
|
68
|
+
def introduction(self) -> str:
|
|
69
|
+
"""
|
|
70
|
+
Returns the introduction of the agent.
|
|
71
|
+
|
|
72
|
+
Returns:
|
|
73
|
+
str: The introduction of the agent.
|
|
74
|
+
"""
|
|
75
|
+
return self._introduction
|
|
76
|
+
|
|
77
|
+
@introduction.setter
|
|
78
|
+
def introduction(self, value) -> None:
|
|
79
|
+
"""
|
|
80
|
+
Sets the introduction of the agent.
|
|
81
|
+
|
|
82
|
+
Args:
|
|
83
|
+
value (str): The introduction of the agent.
|
|
84
|
+
"""
|
|
85
|
+
self._introduction = value
|
|
86
|
+
|
|
87
|
+
@property
|
|
88
|
+
def interface(self) -> list[dict]:
|
|
89
|
+
"""
|
|
90
|
+
Returns the interface of the KG agent.
|
|
91
|
+
|
|
92
|
+
Returns:
|
|
93
|
+
list[dict]: The interface of the KG agent.
|
|
94
|
+
"""
|
|
95
|
+
return self._interface
|
|
96
|
+
|
|
97
|
+
@property
|
|
98
|
+
def kg(self) -> KnowledgeGraph:
|
|
99
|
+
"""
|
|
100
|
+
Returns the KnowledgeGraph object associated with this agent.
|
|
101
|
+
|
|
102
|
+
Returns:
|
|
103
|
+
KnowledgeGraph: The KnowledgeGraph object.
|
|
104
|
+
"""
|
|
105
|
+
return self._kg
|
|
106
|
+
|
|
107
|
+
@kg.setter
|
|
108
|
+
def kg(self, value: KnowledgeGraph) -> None:
|
|
109
|
+
"""
|
|
110
|
+
Sets the knowledge graph for the agent.
|
|
111
|
+
|
|
112
|
+
Args:
|
|
113
|
+
value (KnowledgeGraph): The knowledge graph to be set.
|
|
114
|
+
"""
|
|
115
|
+
self._kg = value
|
|
116
|
+
|
|
117
|
+
def run(self, params: dict) -> str:
|
|
118
|
+
"""
|
|
119
|
+
Ask the agent a question.
|
|
120
|
+
|
|
121
|
+
Args:
|
|
122
|
+
params (dict): The parameters for the agent.
|
|
123
|
+
|
|
124
|
+
Returns:
|
|
125
|
+
str: The agent's response.
|
|
126
|
+
|
|
127
|
+
"""
|
|
128
|
+
output = self.chat_session.send_message(params["prompt"])
|
|
129
|
+
return output['response']
|
|
130
|
+
|
|
131
|
+
def __repr__(self) -> str:
|
|
132
|
+
"""
|
|
133
|
+
Returns a string representation of the KGAgent object.
|
|
134
|
+
|
|
135
|
+
The string representation includes the Agent ID, Knowledge Graph Name,
|
|
136
|
+
Interface, and Introduction.
|
|
137
|
+
|
|
138
|
+
Returns:
|
|
139
|
+
str: A string representation of the KGAgent object.
|
|
140
|
+
"""
|
|
141
|
+
return f"""
|
|
142
|
+
---
|
|
143
|
+
Agent ID: {self.agent_id}
|
|
144
|
+
Knowledge Graph Name: {self._kg.name}
|
|
145
|
+
Interface: {self.interface}
|
|
146
|
+
|
|
147
|
+
Introduction: {self.introduction}
|
|
148
|
+
"""
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import re
|
|
2
|
+
import json
|
|
3
|
+
import logging
|
|
4
|
+
from enum import Enum
|
|
5
|
+
from typing import Union, Optional
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
logger = logging.getLogger(__name__)
|
|
9
|
+
|
|
10
|
+
class AttributeType(Enum):
|
|
11
|
+
"""
|
|
12
|
+
Represents the types of attributes in the system.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
STRING = "string"
|
|
16
|
+
NUMBER = "number"
|
|
17
|
+
BOOLEAN = "boolean"
|
|
18
|
+
LIST = "list"
|
|
19
|
+
POINT = "point"
|
|
20
|
+
MAP = "map"
|
|
21
|
+
VECTOR = "vectorf32"
|
|
22
|
+
|
|
23
|
+
@staticmethod
|
|
24
|
+
def from_string(txt: str) -> "AttributeType":
|
|
25
|
+
"""
|
|
26
|
+
Converts a string representation of an attribute type to its corresponding AttributeType value.
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
txt (str): The string representation of the attribute type.
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
str: The corresponding AttributeType value.
|
|
33
|
+
|
|
34
|
+
Raises:
|
|
35
|
+
ValueError: If the provided attribute type is invalid.
|
|
36
|
+
"""
|
|
37
|
+
# Graph representation of the attribute type
|
|
38
|
+
normalized_txt = txt.lstrip('AttributeType.').lower()
|
|
39
|
+
|
|
40
|
+
# Find the matching attribute type
|
|
41
|
+
if normalized_txt in _SYNONYMS:
|
|
42
|
+
return _SYNONYMS[normalized_txt]
|
|
43
|
+
|
|
44
|
+
raise ValueError(f"Invalid attribute type: {txt}")
|
|
45
|
+
|
|
46
|
+
# Mapping of string representations to AttributeType enum members.
|
|
47
|
+
_SYNONYMS = {
|
|
48
|
+
"string": AttributeType.STRING,
|
|
49
|
+
"integer": AttributeType.NUMBER,
|
|
50
|
+
"float": AttributeType.NUMBER,
|
|
51
|
+
"number": AttributeType.NUMBER,
|
|
52
|
+
"boolean": AttributeType.BOOLEAN,
|
|
53
|
+
"list": AttributeType.LIST,
|
|
54
|
+
"point": AttributeType.POINT,
|
|
55
|
+
"map": AttributeType.MAP,
|
|
56
|
+
"vectorf32": AttributeType.VECTOR,
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
class Attribute:
|
|
60
|
+
""" Represents an attribute of an entity or relation in the ontology.
|
|
61
|
+
|
|
62
|
+
Args:
|
|
63
|
+
name (str): The name of the attribute.
|
|
64
|
+
attr_type (AttributeType): The type of the attribute.
|
|
65
|
+
unique (bool): Whether the attribute is unique.
|
|
66
|
+
required (bool): Whether the attribute is required.
|
|
67
|
+
|
|
68
|
+
Examples:
|
|
69
|
+
>>> attr = Attribute("name", AttributeType.STRING, True, True)
|
|
70
|
+
>>> print(attr)
|
|
71
|
+
name: "string!*"
|
|
72
|
+
"""
|
|
73
|
+
|
|
74
|
+
def __init__(
|
|
75
|
+
self, name: str, attr_type: AttributeType, unique: Optional[bool] = False, required: Optional[bool] = False
|
|
76
|
+
):
|
|
77
|
+
"""
|
|
78
|
+
Initialize a new Attribute object.
|
|
79
|
+
|
|
80
|
+
Args:
|
|
81
|
+
name (str): The name of the attribute.
|
|
82
|
+
attr_type (AttributeType): The type of the attribute.
|
|
83
|
+
unique (Optional[bool]): Indicates whether the attribute should be unique. Defaults to False.
|
|
84
|
+
required (Optional[bool]): Indicates whether the attribute is required. Defaults to False.
|
|
85
|
+
"""
|
|
86
|
+
self.name = re.sub(r"([^a-zA-Z0-9_])", "_", name)
|
|
87
|
+
self.type = attr_type
|
|
88
|
+
self.unique = unique
|
|
89
|
+
self.required = required
|
|
90
|
+
|
|
91
|
+
@staticmethod
|
|
92
|
+
def from_json(txt: Union[str, dict]) -> "Attribute":
|
|
93
|
+
"""
|
|
94
|
+
Creates an Attribute object from a JSON string or dictionary.
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
txt (Union[str, dict]): The JSON string or dictionary representing the Attribute.
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
Attribute: The created Attribute object.
|
|
101
|
+
|
|
102
|
+
"""
|
|
103
|
+
txt = txt if isinstance(txt, dict) else json.loads(txt)
|
|
104
|
+
|
|
105
|
+
return Attribute(
|
|
106
|
+
txt["name"],
|
|
107
|
+
AttributeType.from_string(txt["type"]),
|
|
108
|
+
txt["unique"],
|
|
109
|
+
txt["required"] if "required" in txt else False,
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
@staticmethod
|
|
113
|
+
def from_string(txt: str) -> "Attribute":
|
|
114
|
+
"""
|
|
115
|
+
Parses an attribute from a string.
|
|
116
|
+
The "!" symbol indicates that the attribute is unique.
|
|
117
|
+
The "*" symbol indicates that the attribute is required
|
|
118
|
+
|
|
119
|
+
Args:
|
|
120
|
+
txt (str): The string to parse.
|
|
121
|
+
|
|
122
|
+
Returns:
|
|
123
|
+
Attribute: The parsed attribute.
|
|
124
|
+
|
|
125
|
+
Examples:
|
|
126
|
+
>>> attr = Attribute.from_string("name:string!*")
|
|
127
|
+
>>> print(attr.name)
|
|
128
|
+
name
|
|
129
|
+
|
|
130
|
+
Raises:
|
|
131
|
+
Exception: If the attribute type is invalid.
|
|
132
|
+
"""
|
|
133
|
+
name = txt.split(":")[0].strip()
|
|
134
|
+
attr_type = txt.split(":")[1].split("!")[0].split("*")[0].strip()
|
|
135
|
+
unique = "!" in txt
|
|
136
|
+
required = "*" in txt
|
|
137
|
+
|
|
138
|
+
return Attribute(name, AttributeType.from_string(attr_type), unique, required)
|
|
139
|
+
|
|
140
|
+
def to_json(self) -> dict:
|
|
141
|
+
"""
|
|
142
|
+
Converts the attribute object to a JSON representation.
|
|
143
|
+
|
|
144
|
+
Returns:
|
|
145
|
+
dict: A dictionary representing the attribute object in JSON format.
|
|
146
|
+
The dictionary contains the following keys:
|
|
147
|
+
- "name": The name of the attribute.
|
|
148
|
+
- "type": The type of the attribute.
|
|
149
|
+
- "unique": A boolean indicating whether the attribute is unique.
|
|
150
|
+
- "required": A boolean indicating whether the attribute is required.
|
|
151
|
+
"""
|
|
152
|
+
json_data = {
|
|
153
|
+
"name": self.name,
|
|
154
|
+
"type": self.type.value,
|
|
155
|
+
"unique": self.unique,
|
|
156
|
+
"required": self.required,
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return json_data
|
|
160
|
+
|
|
161
|
+
def __str__(self) -> str:
|
|
162
|
+
"""
|
|
163
|
+
Returns a string representation of the Attribute object.
|
|
164
|
+
|
|
165
|
+
The string representation includes the attribute name, type, uniqueness, and requirement status.
|
|
166
|
+
|
|
167
|
+
Returns:
|
|
168
|
+
str: A string representation of the Attribute object.
|
|
169
|
+
"""
|
|
170
|
+
return f"{self.name}: \"{self.type}{'!' if self.unique else ''}{'*' if self.required else ''}\""
|