spinta 0.2.dev17__py3-none-any.whl → 0.2.dev19__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.
- spinta/__init__.py +2 -0
- spinta/backends/postgresql/commands/summary.py +2 -2
- spinta/datasets/backends/dataframe/ufuncs/query/ufuncs.py +18 -5
- spinta/exceptions.py +6 -0
- spinta/manifests/dict/components.py +102 -1
- spinta/manifests/dict/helpers.py +271 -297
- spinta/manifests/helpers.py +3 -3
- spinta/manifests/open_api/helpers.py +7 -2
- spinta/manifests/open_api/openapi_config.py +0 -58
- spinta/manifests/open_api/openapi_generator.py +473 -226
- spinta/manifests/sql/helpers.py +8 -2
- spinta/manifests/tabular/helpers.py +5 -0
- spinta/nodes.py +4 -0
- spinta/testing/pytest.py +6 -2
- {spinta-0.2.dev17.dist-info → spinta-0.2.dev19.dist-info}/METADATA +1 -1
- {spinta-0.2.dev17.dist-info → spinta-0.2.dev19.dist-info}/RECORD +19 -19
- {spinta-0.2.dev17.dist-info → spinta-0.2.dev19.dist-info}/WHEEL +0 -0
- {spinta-0.2.dev17.dist-info → spinta-0.2.dev19.dist-info}/entry_points.txt +0 -0
- {spinta-0.2.dev17.dist-info → spinta-0.2.dev19.dist-info}/licenses/LICENSE +0 -0
spinta/__init__.py
CHANGED
|
@@ -6,7 +6,7 @@ from spinta.backends.helpers import get_table_name
|
|
|
6
6
|
from spinta.backends.postgresql.helpers.name import get_pg_table_name, get_pg_column_name
|
|
7
7
|
from spinta.core.ufuncs import Expr
|
|
8
8
|
from spinta.types.datatype import Integer, Number, Boolean, String, Date, DateTime, Time, Ref
|
|
9
|
-
from spinta import commands
|
|
9
|
+
from spinta import commands, HTTP_URL_PREFIXES
|
|
10
10
|
from spinta.components import Context, Property
|
|
11
11
|
from spinta.components import Model
|
|
12
12
|
from spinta.exceptions import NotFoundError, NotImplementedFeature, InvalidRequestQuery
|
|
@@ -322,7 +322,7 @@ def summary(context: Context, dtype: Ref, backend: PostgreSQL, **kwargs):
|
|
|
322
322
|
prefixes = dtype.model.external.dataset.prefixes
|
|
323
323
|
label = None
|
|
324
324
|
if uri and ":" in uri:
|
|
325
|
-
if uri.startswith(
|
|
325
|
+
if uri.startswith(HTTP_URL_PREFIXES):
|
|
326
326
|
label = uri
|
|
327
327
|
else:
|
|
328
328
|
split = uri.split(":")
|
|
@@ -15,7 +15,7 @@ from spinta.datasets.backends.dataframe.ufuncs.query.components import (
|
|
|
15
15
|
)
|
|
16
16
|
from spinta.datasets.components import Param
|
|
17
17
|
from spinta.datasets.utils import iterparams
|
|
18
|
-
from spinta.exceptions import PropertyNotFound, NotImplementedFeature, SourceCannotBeList
|
|
18
|
+
from spinta.exceptions import PropertyNotFound, NotImplementedFeature, SourceCannotBeList, SourceOrPrepareNotAllowed
|
|
19
19
|
from spinta.types.datatype import DataType, PrimaryKey, Ref
|
|
20
20
|
from spinta.types.text.components import Text
|
|
21
21
|
from spinta.ufuncs.components import ForeignProperty
|
|
@@ -188,9 +188,12 @@ def select(env: DaskDataFrameQueryBuilder, prop: Property) -> Selected:
|
|
|
188
188
|
# tag:resolving_private_properties_in_prepare_context
|
|
189
189
|
result = env.call("select", prop.dtype, result)
|
|
190
190
|
elif prop.external.prepare is not NA:
|
|
191
|
-
# property without external name
|
|
192
|
-
|
|
193
|
-
|
|
191
|
+
# property without external name may be evaluated already, if it is use the value
|
|
192
|
+
if isinstance(prop.external.prepare, Expr):
|
|
193
|
+
result = env(this=prop).resolve(prop.external.prepare)
|
|
194
|
+
result = env.call("select", prop.dtype, result)
|
|
195
|
+
else:
|
|
196
|
+
result = Selected(prop=prop, prep=prop.external.prepare)
|
|
194
197
|
elif prop.external and prop.external.name:
|
|
195
198
|
# If prepare is not given, then take value from `source`.
|
|
196
199
|
result = env.call("select", prop.dtype)
|
|
@@ -339,7 +342,7 @@ def select(
|
|
|
339
342
|
) -> Selected:
|
|
340
343
|
# TODO need join for this to work
|
|
341
344
|
return Selected(
|
|
342
|
-
item=dtype.prop.name,
|
|
345
|
+
item=dtype.prop.external.name,
|
|
343
346
|
prop=dtype.prop,
|
|
344
347
|
)
|
|
345
348
|
|
|
@@ -458,3 +461,13 @@ def eval_(env: DaskDataFrameQueryBuilder, param: Param) -> Iterator[str]:
|
|
|
458
461
|
)
|
|
459
462
|
|
|
460
463
|
return resolved_values
|
|
464
|
+
|
|
465
|
+
|
|
466
|
+
@ufunc.resolver(DaskDataFrameQueryBuilder, Bind, Bind, name="getattr")
|
|
467
|
+
def getattr_(env: DaskDataFrameQueryBuilder, obj: Bind, attr: Bind) -> Any:
|
|
468
|
+
return GetAttr(obj, attr)
|
|
469
|
+
|
|
470
|
+
|
|
471
|
+
@ufunc.resolver(DaskDataFrameQueryBuilder, Bind, Bind, Bind, name="getattr")
|
|
472
|
+
def getattr_(env: DaskDataFrameQueryBuilder, source: Bind, obj: Bind, attr: Bind) -> Any:
|
|
473
|
+
raise SourceOrPrepareNotAllowed(source=str(source))
|
spinta/exceptions.py
CHANGED
|
@@ -1215,3 +1215,9 @@ class EnumPrepareMissing(UserError):
|
|
|
1215
1215
|
template = """
|
|
1216
1216
|
Enum {enum} is missing a required value in the prepare column.
|
|
1217
1217
|
"""
|
|
1218
|
+
|
|
1219
|
+
|
|
1220
|
+
class SourceOrPrepareNotAllowed(UserError):
|
|
1221
|
+
template = """
|
|
1222
|
+
The source {source} was not expected. Delete it from the manifest or update the prepare function to allow it.
|
|
1223
|
+
"""
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import dataclasses
|
|
1
2
|
from enum import Enum
|
|
2
3
|
|
|
3
|
-
|
|
4
4
|
from spinta.manifests.components import Manifest
|
|
5
|
+
from spinta.manifests.helpers import TypeDetector
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
class DictFormat(Enum):
|
|
@@ -30,3 +31,103 @@ class XmlManifest(DictManifest):
|
|
|
30
31
|
@staticmethod
|
|
31
32
|
def detect_from_path(path: str) -> bool:
|
|
32
33
|
return path.endswith(".xml")
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@dataclasses.dataclass
|
|
37
|
+
class _MappedProperties:
|
|
38
|
+
name: str
|
|
39
|
+
source: str
|
|
40
|
+
extra: str
|
|
41
|
+
type_detector: TypeDetector
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
@dataclasses.dataclass
|
|
45
|
+
class _MappedModels:
|
|
46
|
+
name: str
|
|
47
|
+
source: str
|
|
48
|
+
properties: dict[str, _MappedProperties]
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@dataclasses.dataclass
|
|
52
|
+
class _MappedDataset:
|
|
53
|
+
dataset: str
|
|
54
|
+
resource: str
|
|
55
|
+
models: dict[str, dict[str, _MappedModels]]
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
@dataclasses.dataclass
|
|
59
|
+
class _MappingMeta:
|
|
60
|
+
is_blank_node: bool
|
|
61
|
+
blank_node_name: str
|
|
62
|
+
blank_node_source: str
|
|
63
|
+
seperator: str
|
|
64
|
+
recursive_descent: str
|
|
65
|
+
remove_array_suffix: bool
|
|
66
|
+
model_source_prefix: str
|
|
67
|
+
check_namespace: bool
|
|
68
|
+
namespace_prefixes: dict[str, list[str]]
|
|
69
|
+
namespace_seperator: str
|
|
70
|
+
|
|
71
|
+
@classmethod
|
|
72
|
+
def get_for(cls, manifest_type: DictFormat) -> "_MappingMeta":
|
|
73
|
+
if manifest_type == DictFormat.JSON:
|
|
74
|
+
mapping_meta = _MappingMeta.for_json()
|
|
75
|
+
elif manifest_type in (DictFormat.XML, DictFormat.HTML):
|
|
76
|
+
mapping_meta = _MappingMeta.for_xml()
|
|
77
|
+
else:
|
|
78
|
+
mapping_meta = _MappingMeta.default()
|
|
79
|
+
|
|
80
|
+
return mapping_meta
|
|
81
|
+
|
|
82
|
+
@classmethod
|
|
83
|
+
def for_json(cls) -> "_MappingMeta":
|
|
84
|
+
return cls(
|
|
85
|
+
is_blank_node=False,
|
|
86
|
+
blank_node_name="model1",
|
|
87
|
+
blank_node_source=".",
|
|
88
|
+
seperator=".",
|
|
89
|
+
recursive_descent=".",
|
|
90
|
+
model_source_prefix="",
|
|
91
|
+
namespace_seperator=":",
|
|
92
|
+
remove_array_suffix=False,
|
|
93
|
+
check_namespace=False,
|
|
94
|
+
namespace_prefixes={},
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
@classmethod
|
|
98
|
+
def for_xml(cls) -> "_MappingMeta":
|
|
99
|
+
return cls(
|
|
100
|
+
is_blank_node=False,
|
|
101
|
+
blank_node_name="model1",
|
|
102
|
+
blank_node_source=".",
|
|
103
|
+
seperator="/",
|
|
104
|
+
recursive_descent="/..",
|
|
105
|
+
model_source_prefix="/",
|
|
106
|
+
namespace_seperator=":",
|
|
107
|
+
remove_array_suffix=True,
|
|
108
|
+
check_namespace=True,
|
|
109
|
+
namespace_prefixes={"xmlns": ["xmlns", "@xmlns"]},
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
@classmethod
|
|
113
|
+
def default(cls) -> "_MappingMeta":
|
|
114
|
+
return cls(
|
|
115
|
+
is_blank_node=False,
|
|
116
|
+
blank_node_name="model1",
|
|
117
|
+
blank_node_source=".",
|
|
118
|
+
seperator="",
|
|
119
|
+
recursive_descent="",
|
|
120
|
+
model_source_prefix="",
|
|
121
|
+
namespace_seperator=":",
|
|
122
|
+
remove_array_suffix=False,
|
|
123
|
+
check_namespace=False,
|
|
124
|
+
namespace_prefixes={},
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
@dataclasses.dataclass
|
|
129
|
+
class _MappingScope:
|
|
130
|
+
parent_scope: str
|
|
131
|
+
model_scope: str
|
|
132
|
+
model_name: str
|
|
133
|
+
property_name: str
|