sinapsis-aperturedb 0.1.0__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.
- sinapsis_aperturedb/__init__.py +0 -0
- sinapsis_aperturedb/helpers/__init__.py +0 -0
- sinapsis_aperturedb/helpers/aperturedb_env_var_keys.py +60 -0
- sinapsis_aperturedb/helpers/query_base_models/__init__.py +0 -0
- sinapsis_aperturedb/helpers/query_base_models/add.py +34 -0
- sinapsis_aperturedb/helpers/query_base_models/base.py +165 -0
- sinapsis_aperturedb/helpers/query_base_models/delete.py +38 -0
- sinapsis_aperturedb/helpers/query_base_models/find.py +52 -0
- sinapsis_aperturedb/helpers/query_base_models/update.py +72 -0
- sinapsis_aperturedb/helpers/tags.py +7 -0
- sinapsis_aperturedb/templates/__init__.py +22 -0
- sinapsis_aperturedb/templates/aperturedb_add_to_table.py +72 -0
- sinapsis_aperturedb/templates/aperturedb_client_base.py +234 -0
- sinapsis_aperturedb/templates/aperturedb_database_info.py +43 -0
- sinapsis_aperturedb/templates/aperturedb_delete_from_table.py +27 -0
- sinapsis_aperturedb/templates/aperturedb_find_in_table.py +23 -0
- sinapsis_aperturedb/templates/aperturedb_update_table.py +30 -0
- sinapsis_aperturedb-0.1.0.dist-info/METADATA +238 -0
- sinapsis_aperturedb-0.1.0.dist-info/RECORD +22 -0
- sinapsis_aperturedb-0.1.0.dist-info/WHEEL +5 -0
- sinapsis_aperturedb-0.1.0.dist-info/licenses/LICENSE +661 -0
- sinapsis_aperturedb-0.1.0.dist-info/top_level.txt +1 -0
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
from pydantic import BaseModel
|
|
5
|
+
from sinapsis_core.utils.env_var_keys import EnvVarEntry, doc_str, return_docs_for_vars
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class _ApertureDBEnvVars(BaseModel):
|
|
9
|
+
"""Env vars for ApertureDB."""
|
|
10
|
+
|
|
11
|
+
APERTUREDB_API_KEY: EnvVarEntry = EnvVarEntry(
|
|
12
|
+
var_name="APERTUREDB_API_KEY",
|
|
13
|
+
default_value="",
|
|
14
|
+
allowed_values=None,
|
|
15
|
+
description="set api key for ApertureDB",
|
|
16
|
+
)
|
|
17
|
+
APERTUREDB_HOST: EnvVarEntry = EnvVarEntry(
|
|
18
|
+
var_name="APERTUREDB_HOST",
|
|
19
|
+
default_value="localhost",
|
|
20
|
+
allowed_values=None,
|
|
21
|
+
description="set host for ApertureDB",
|
|
22
|
+
)
|
|
23
|
+
APERTUREDB_USER: EnvVarEntry = EnvVarEntry(
|
|
24
|
+
var_name="APERTUREDB_USER",
|
|
25
|
+
default_value="",
|
|
26
|
+
allowed_values=None,
|
|
27
|
+
description="set user for ApertureDB",
|
|
28
|
+
)
|
|
29
|
+
APERTUREDB_PASSWORD: EnvVarEntry = EnvVarEntry(
|
|
30
|
+
var_name="APERTUREDB_PASSWORD",
|
|
31
|
+
default_value="",
|
|
32
|
+
allowed_values=None,
|
|
33
|
+
description="set password for ApertureDB",
|
|
34
|
+
)
|
|
35
|
+
APERTUREDB_PORT: EnvVarEntry = EnvVarEntry(
|
|
36
|
+
var_name="APERTUREDB_PORT",
|
|
37
|
+
default_value="55555",
|
|
38
|
+
allowed_values=None,
|
|
39
|
+
description="set port for ApertureDB",
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
ApertureDBEnvVars = _ApertureDBEnvVars()
|
|
44
|
+
|
|
45
|
+
doc_str = return_docs_for_vars(
|
|
46
|
+
ApertureDBEnvVars,
|
|
47
|
+
docs=doc_str,
|
|
48
|
+
string_for_doc="""ApertureDB env vars available: \n""",
|
|
49
|
+
)
|
|
50
|
+
__doc__ = doc_str
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def __getattr__(name: str) -> Any:
|
|
54
|
+
if name in ApertureDBEnvVars.model_fields:
|
|
55
|
+
return ApertureDBEnvVars.model_fields[name].default.value
|
|
56
|
+
|
|
57
|
+
raise AttributeError(f"Agent does not have `{name}` env var")
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
_all__ = (*list(ApertureDBEnvVars.model_fields.keys()), "ApertureDBEnvVars")
|
|
File without changes
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
from pydantic import Field
|
|
4
|
+
|
|
5
|
+
from sinapsis_aperturedb.helpers.query_base_models.base import (
|
|
6
|
+
ConstraintsType,
|
|
7
|
+
CreateConnectionType,
|
|
8
|
+
DateType,
|
|
9
|
+
QueryParameters,
|
|
10
|
+
ReferenceType,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class BaseAddParameters(QueryParameters):
|
|
15
|
+
"""Base class for Add_ commands parameters.
|
|
16
|
+
|
|
17
|
+
[optional] _ref: reference to be used within the transaction.
|
|
18
|
+
[optional] properties: key-value pairs associated with objects (Entity, Image, Video, Descriptor, etc) and connections.
|
|
19
|
+
[optional] if_not_found: When using if_not_found, an Add* command (AddEntity, etc) will become a "conditional add"
|
|
20
|
+
the object will be inserted into the database if and only if there is no other element of the same type that
|
|
21
|
+
fulfills the specified constraints
|
|
22
|
+
[optional] connect
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
ref: ReferenceType | None = Field(alias="_ref", default=None)
|
|
26
|
+
properties: dict[str, int | float | str | bool | DateType] | None = None
|
|
27
|
+
if_not_found: ConstraintsType | None = None
|
|
28
|
+
connect: CreateConnectionType | None = None
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class AddEntityParameters(BaseAddParameters):
|
|
32
|
+
"""AddEntity class: name of entity class."""
|
|
33
|
+
|
|
34
|
+
class_: str = Field(alias="class")
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
from typing import Annotated, Any, Literal, Tuple
|
|
3
|
+
|
|
4
|
+
from pydantic import BaseModel, Field
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class ConnectionParams(BaseModel):
|
|
8
|
+
"""Model to store connection parameters to ApertureDB server."""
|
|
9
|
+
|
|
10
|
+
host: str | None = None
|
|
11
|
+
user: str | None = None
|
|
12
|
+
port: int | None = None
|
|
13
|
+
password: str | None = None
|
|
14
|
+
key: str | None = None
|
|
15
|
+
use_ssl: bool | None = None
|
|
16
|
+
|
|
17
|
+
def get_connection_params(self) -> dict[str, Any]:
|
|
18
|
+
"""Get connection parameters as a dictionary, excluding None and unset values."""
|
|
19
|
+
conn_params = self.model_dump(exclude_none=True, exclude_unset=True)
|
|
20
|
+
return conn_params
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class QueryParameters(BaseModel):
|
|
24
|
+
"""Base class for query parameters."""
|
|
25
|
+
|
|
26
|
+
def get_parameters(self) -> dict[str, Any]:
|
|
27
|
+
"""Format parameters as a dictionary. Excludes any not set."""
|
|
28
|
+
dumped_model = self.model_dump(mode="json", by_alias=True, exclude_unset=True, exclude_none=True)
|
|
29
|
+
return self.remove_empty_dicts(dumped_model)
|
|
30
|
+
|
|
31
|
+
@staticmethod
|
|
32
|
+
def remove_empty_dicts(data: dict) -> dict:
|
|
33
|
+
"""Remove empty dictionaries and lists from the input dictionary.
|
|
34
|
+
|
|
35
|
+
Parameters
|
|
36
|
+
----------
|
|
37
|
+
data (dict): Dictionary to filter.
|
|
38
|
+
|
|
39
|
+
Returns:
|
|
40
|
+
-------
|
|
41
|
+
dict: Dictionary with None values and empty dicts/lists removed.
|
|
42
|
+
"""
|
|
43
|
+
return {k: v for k, v in data.items() if v is not None and (not isinstance(v, (dict, list)) or len(v) > 0)}
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class Query(BaseModel):
|
|
47
|
+
"""Query base model."""
|
|
48
|
+
|
|
49
|
+
command: str
|
|
50
|
+
parameters: QueryParameters
|
|
51
|
+
blobs: list[bytes] | None = None
|
|
52
|
+
|
|
53
|
+
def prepare_query(self) -> Tuple[dict[str, Any], list[bytes]]:
|
|
54
|
+
"""Format the query as a dictionary required by ApertureDB.
|
|
55
|
+
|
|
56
|
+
A query is composed of:
|
|
57
|
+
a string representing a JSON array of one or more commands, and
|
|
58
|
+
[optional] an "array of blobs".
|
|
59
|
+
|
|
60
|
+
"""
|
|
61
|
+
query = {self.command: self.parameters.get_parameters()}
|
|
62
|
+
if self.blobs:
|
|
63
|
+
return query, self.blobs
|
|
64
|
+
return query, []
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class Response(BaseModel):
|
|
68
|
+
"""Base model to store ApertureDB responses.
|
|
69
|
+
|
|
70
|
+
The JSON response is an array of objects where each member gives information about how a particular command executed.
|
|
71
|
+
|
|
72
|
+
status: Indicates execution status (e.g., 0 for success).
|
|
73
|
+
returned: Indicates the number of entities, connections, or blobs returned. If the user requests only aggregated values (e.g., sum, average) or uses _ref without requesting any properties, "returned" will be 0.
|
|
74
|
+
entities/connections [Optional]: Included only when the user explicitly requests property values.
|
|
75
|
+
blobs_start[Optional]: Included only if blobs=true was set in the query. Indicates the 0-based index in the return vector where blob data for this command begins.
|
|
76
|
+
_blob_index[Optional]: Included in each entity only if blobs=true. Indicates the blob's position relative to the full return vector.
|
|
77
|
+
|
|
78
|
+
"""
|
|
79
|
+
|
|
80
|
+
status: int
|
|
81
|
+
info: str | None = None
|
|
82
|
+
returned: int | None = None
|
|
83
|
+
entities: list[dict[str, Any]] | dict[str, Any] | None = None
|
|
84
|
+
connections: list[dict[str, Any]] | dict[str, Any] | None = None
|
|
85
|
+
blobs_start: int | None = None
|
|
86
|
+
command: str | None = Field(exclude=True, default=None)
|
|
87
|
+
|
|
88
|
+
def format_response_dict(self) -> dict[str, Any]:
|
|
89
|
+
"""Format the response as a dictionary.
|
|
90
|
+
|
|
91
|
+
If a command is set, returns a dictionary with the command as the key.
|
|
92
|
+
Otherwise, returns the response dictionary directly.
|
|
93
|
+
|
|
94
|
+
Returns:
|
|
95
|
+
-------
|
|
96
|
+
dict[str, Any]: Formatted response dictionary.
|
|
97
|
+
"""
|
|
98
|
+
response_dict = self.model_dump(mode="json", exclude_unset=True)
|
|
99
|
+
if self.command is not None:
|
|
100
|
+
return {self.command: response_dict}
|
|
101
|
+
return response_dict
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
# ------------Parameter types
|
|
105
|
+
ReferenceType = Annotated[int, Field(ge=1, le=100000)]
|
|
106
|
+
ConstraintsType = list[Any] | dict[str, Any] | None
|
|
107
|
+
ImageFormatType = Literal["jpg", "png"]
|
|
108
|
+
EngineType = Literal["Flat", "IVF", "HNSW"]
|
|
109
|
+
MetricType = Literal["L2", "IP", "CS"]
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
class ConnectionRef(BaseModel):
|
|
113
|
+
ref: ReferenceType | None = None
|
|
114
|
+
connection_class: str | None = None
|
|
115
|
+
constraints: ConstraintsType = None
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
class IsConnectedTo(BaseModel):
|
|
119
|
+
ref: ReferenceType | None = None
|
|
120
|
+
connection_class: str | None = None
|
|
121
|
+
constraints: ConstraintsType | None = None
|
|
122
|
+
any: list[ConnectionRef] | None = None
|
|
123
|
+
in_: list[ConnectionRef] | None = Field(alias="in", default=None)
|
|
124
|
+
out: list[ConnectionRef] | None = None
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
class ResultsType(BaseModel):
|
|
128
|
+
list_: list[str] | None = Field(alias="list", default=None)
|
|
129
|
+
all_properties: bool | None = None
|
|
130
|
+
count: bool | None = None
|
|
131
|
+
sum: str | list[str] | None = None
|
|
132
|
+
average: str | list[str] | None = None
|
|
133
|
+
min: str | list[str] | None = None
|
|
134
|
+
max: str | list[str] | None = None
|
|
135
|
+
group: list[str] | None = None
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
class BatchType(BaseModel):
|
|
139
|
+
batches: int | None = None
|
|
140
|
+
batch_size: int | None = None
|
|
141
|
+
batch_id: int | None = None
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
class DateType(BaseModel):
|
|
145
|
+
"""datetime (ISO 8601 representation)."""
|
|
146
|
+
|
|
147
|
+
date: str = Field(alias="_date")
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
class CreateConnectionType(BaseModel):
|
|
151
|
+
"""ref: Reference to other objects within the transaction.
|
|
152
|
+
|
|
153
|
+
[optional] class: Name of the class that is used to describe the relationship between the objects.
|
|
154
|
+
[optional] direction: [in, out]. Default is "out. "in" indicates that the relationship actually ends at the object
|
|
155
|
+
(object) in the Add*.
|
|
156
|
+
"""
|
|
157
|
+
|
|
158
|
+
ref: ReferenceType
|
|
159
|
+
class_: str | None = Field(alias="class", default=None)
|
|
160
|
+
direction: Literal["in", "out"] | None = None
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
class GetSchemaParameters(QueryParameters):
|
|
164
|
+
ref: ReferenceType | None = None
|
|
165
|
+
type: Literal["entities", "connections", "both"] | None = None
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
from sinapsis_aperturedb.helpers.query_base_models.base import (
|
|
5
|
+
ConstraintsType,
|
|
6
|
+
QueryParameters,
|
|
7
|
+
ReferenceType,
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class BaseDeleteParameters(QueryParameters):
|
|
12
|
+
"""Base parameters for Delete_ commands.
|
|
13
|
+
|
|
14
|
+
[optional] ref: Reference to other entity objects within the transaction.
|
|
15
|
+
[optional] constraints
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
ref: ReferenceType | None = None
|
|
19
|
+
constraints: ConstraintsType | None = None
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class DeleteEntityParameters(BaseDeleteParameters):
|
|
23
|
+
"""Parameters for DeleteEntity command.
|
|
24
|
+
|
|
25
|
+
[optional] with_class: Specifies the entity class.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
with_class: str | None = None
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class DeleteDescriptorSetParameters(BaseDeleteParameters):
|
|
32
|
+
"""Parameters for DeleteDescriptorSet command.
|
|
33
|
+
|
|
34
|
+
[optional] background: Differs deletion of the set and associated descriptions as a background task.
|
|
35
|
+
Defaults to false.
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
set: str
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
from pydantic import Field
|
|
3
|
+
|
|
4
|
+
from sinapsis_aperturedb.helpers.query_base_models.base import (
|
|
5
|
+
BatchType,
|
|
6
|
+
ConstraintsType,
|
|
7
|
+
IsConnectedTo,
|
|
8
|
+
QueryParameters,
|
|
9
|
+
ReferenceType,
|
|
10
|
+
ResultsType,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class BaseFindParameters(QueryParameters):
|
|
15
|
+
"""Base parameters for Find_ commands.
|
|
16
|
+
|
|
17
|
+
[optional] _ref: Reference to be used within the transaction.
|
|
18
|
+
[optional] unique: Indicates whether a single object is expected to satisfy the constraints.
|
|
19
|
+
[optional] constraints: used to specify search/filter criteria over the properties defined for objects
|
|
20
|
+
[optional] is_connected_to: specifies one or more connection-based constraints that must be satisfied in a Find* command
|
|
21
|
+
[optional] group_by_source: specifies in a Find* command the result is a set of objects connected to the referenced
|
|
22
|
+
Find* command by connections as defined by the is_connected_to parameter
|
|
23
|
+
[optional] results: Defines the information returned in the JSON response as a result of a Find* command
|
|
24
|
+
[optional] batch: specify a query that can be used by multiple workers to retrieve a portion of the results
|
|
25
|
+
[optional] sort: specifies how the results will be sorted on the response, and which properties will be used for sorting
|
|
26
|
+
[optional] limit: specifies the maximum number of elements that will be returned.
|
|
27
|
+
[optional] offset: specifies the number of results that will be skipped
|
|
28
|
+
[optional] uniqueids: indicates whether unique ids will be returned as part of the response (Default: false).
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
ref: ReferenceType | None = Field(alias="_ref", default=None)
|
|
34
|
+
unique: bool | None = None
|
|
35
|
+
constraints: ConstraintsType | None = Field(default=None)
|
|
36
|
+
is_connected_to: IsConnectedTo = Field(default_factory=dict)
|
|
37
|
+
group_by_source: bool | None = None
|
|
38
|
+
results: ResultsType = Field(default_factory=dict)
|
|
39
|
+
batch: BatchType = Field(default_factory=dict)
|
|
40
|
+
sort: str | dict[str, str] | list[dict[str, str]] | None = None
|
|
41
|
+
limit: int | None = None
|
|
42
|
+
offset: int | None = None
|
|
43
|
+
uniqueids: bool | None = None
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class FindEntityParameters(BaseFindParameters):
|
|
47
|
+
"""Parameters for FindEntity command.
|
|
48
|
+
|
|
49
|
+
[optional] with_class: Name of entity class.
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
with_class: str | None = None
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
from sinapsis_aperturedb.helpers.query_base_models.base import (
|
|
3
|
+
ConstraintsType,
|
|
4
|
+
DateType,
|
|
5
|
+
QueryParameters,
|
|
6
|
+
RectangleType,
|
|
7
|
+
ReferenceType,
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class BaseUpdateParameters(QueryParameters):
|
|
12
|
+
"""Base parameters for Update_ commands.
|
|
13
|
+
|
|
14
|
+
[optional] ref: Reference to other entities within the transaction.
|
|
15
|
+
[optional] constraints: used to specify search/filter criteria over the properties defined for objects
|
|
16
|
+
[optional] properties: key-value pairs associated with objects (Entity, Image, Video, Descriptor, etc) and connections.
|
|
17
|
+
[optional] remove_props: list of property keys that will be removed as part of an Update* command.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
ref: ReferenceType | None = None
|
|
21
|
+
constraints: ConstraintsType | None = None
|
|
22
|
+
properties: dict[str, int | float | str | bool | DateType] | None = None
|
|
23
|
+
remove_props: list[str] | None = None
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class UpdateEntityParameters(BaseUpdateParameters):
|
|
27
|
+
"""Parameters for UpdateEntity command.
|
|
28
|
+
|
|
29
|
+
[optional] with_class: name of entity class.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
with_class: str | None = None
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class UpdateBoundingBoxParameters(BaseUpdateParameters):
|
|
36
|
+
"""Parameters for UpdateBoundingBox command.
|
|
37
|
+
|
|
38
|
+
[optional] rectangle
|
|
39
|
+
[optional] label
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
rectangle: RectangleType | None = None
|
|
43
|
+
label: str | None = None
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class UpdatePolygonParameters(BaseUpdateParameters):
|
|
47
|
+
"""Parameters for UpdatePolygon command.
|
|
48
|
+
|
|
49
|
+
[optional] polygons
|
|
50
|
+
[optional] label
|
|
51
|
+
"""
|
|
52
|
+
|
|
53
|
+
polygons: list[list[list[int | float]]] | None = None
|
|
54
|
+
label: str | None = None
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class UpdateDescriptorSetParameters(BaseUpdateParameters):
|
|
58
|
+
"""Parameters for UpdateDescriptorSet command.
|
|
59
|
+
|
|
60
|
+
[optional] with_name: name of the set.
|
|
61
|
+
"""
|
|
62
|
+
|
|
63
|
+
with_name: str | None = None
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class UpdateDescriptorParameters(BaseUpdateParameters):
|
|
67
|
+
"""Parameters for UpdateDescriptor command.
|
|
68
|
+
|
|
69
|
+
[optional] with_name: name of the set.
|
|
70
|
+
"""
|
|
71
|
+
|
|
72
|
+
label: str | None = None
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
import importlib
|
|
3
|
+
from typing import Callable, cast
|
|
4
|
+
|
|
5
|
+
_root_lib_path = "sinapsis_aperturedb.templates"
|
|
6
|
+
|
|
7
|
+
_template_lookup: dict = {
|
|
8
|
+
"ApertureDBGetStatus": f"{_root_lib_path}.aperturedb_client_base",
|
|
9
|
+
"ApertureDBFindEntities": f"{_root_lib_path}.aperturedb_find_in_table",
|
|
10
|
+
"ApertureDBAddEntitiesFromCSV": f"{_root_lib_path}.aperturedb_add_to_table",
|
|
11
|
+
"ApertureDBGetSchema": f"{_root_lib_path}.aperturedb_database_info",
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def __getattr__(name: str) -> Callable:
|
|
16
|
+
if name in _template_lookup:
|
|
17
|
+
module = importlib.import_module(_template_lookup[name])
|
|
18
|
+
return cast(Callable, getattr(module, name))
|
|
19
|
+
raise AttributeError(f"template `{name}` not found in {_root_lib_path}")
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
__all__ = list(_template_lookup.keys())
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
import pandas as pd
|
|
3
|
+
from pydantic.dataclasses import dataclass
|
|
4
|
+
from sinapsis_core.data_containers.data_packet import DataContainer
|
|
5
|
+
|
|
6
|
+
from sinapsis_aperturedb.helpers.query_base_models.add import (
|
|
7
|
+
AddEntityParameters,
|
|
8
|
+
)
|
|
9
|
+
from sinapsis_aperturedb.helpers.query_base_models.base import (
|
|
10
|
+
Query,
|
|
11
|
+
)
|
|
12
|
+
from sinapsis_aperturedb.templates.aperturedb_client_base import (
|
|
13
|
+
ApertureDBClientQuery,
|
|
14
|
+
ApertureDBClientQueryAttributes,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@dataclass
|
|
19
|
+
class ApertureDBAddEntitiesFromCSVKeys:
|
|
20
|
+
records: str = "records"
|
|
21
|
+
class_: str = "class"
|
|
22
|
+
properties: str = "properties"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class ApertureDBAddEntitiesFromCSV(ApertureDBClientQuery):
|
|
26
|
+
"""Template to add Entities from a CSV file.
|
|
27
|
+
|
|
28
|
+
This template receives a CSV as a pandas dataframe within the DataContainer, then
|
|
29
|
+
creates queries to add Entities from the CSV with one of the columns' names to be used as
|
|
30
|
+
the Entity class name.
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
COMMAND = "AddEntity"
|
|
34
|
+
|
|
35
|
+
class ApertureDBAddEntitiesFromCSVAttributes(ApertureDBClientQueryAttributes):
|
|
36
|
+
"""Attributes for ApertureDBAddEntity template.
|
|
37
|
+
|
|
38
|
+
class_column: name of the column which will be used as class name. Case sensitive
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
class_column: str
|
|
42
|
+
generic_key: str
|
|
43
|
+
|
|
44
|
+
AttributesBaseModel = ApertureDBAddEntitiesFromCSVAttributes
|
|
45
|
+
|
|
46
|
+
def execute(self, container: DataContainer) -> DataContainer:
|
|
47
|
+
"""Gets CSV data from the pandas dataframe and creates an AddEntity query for each row.
|
|
48
|
+
|
|
49
|
+
Args:
|
|
50
|
+
container (DataContainer): The container holding the input data packets.
|
|
51
|
+
|
|
52
|
+
Returns:
|
|
53
|
+
DataContainer: The updated container with responses
|
|
54
|
+
"""
|
|
55
|
+
csv_dataframe: pd.DataFrame = self._get_generic_data(container)
|
|
56
|
+
|
|
57
|
+
if not isinstance(csv_dataframe, pd.DataFrame):
|
|
58
|
+
self.logger.warning("Received CSV data must be a pandas dataframe object. Returning input datacontainer.")
|
|
59
|
+
return container
|
|
60
|
+
|
|
61
|
+
queries = []
|
|
62
|
+
for record in csv_dataframe.to_dict(ApertureDBAddEntitiesFromCSVKeys.records):
|
|
63
|
+
entity = {}
|
|
64
|
+
class_value = record.pop(self.attributes.class_column)
|
|
65
|
+
entity[ApertureDBAddEntitiesFromCSVKeys.class_] = class_value
|
|
66
|
+
entity[ApertureDBAddEntitiesFromCSVKeys.properties] = record
|
|
67
|
+
parameters = AddEntityParameters(**entity)
|
|
68
|
+
query_base_model = Query(command=self.COMMAND, parameters=parameters)
|
|
69
|
+
queries.append(query_base_model.prepare_query()[0])
|
|
70
|
+
|
|
71
|
+
self.process_query_list(queries, container)
|
|
72
|
+
return container
|