ogc-na 0.3.43__py3-none-any.whl → 0.3.45__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.
Potentially problematic release.
This version of ogc-na might be problematic. Click here for more details.
- ogc/na/_version.py +2 -2
- ogc/na/annotate_schema.py +36 -21
- ogc/na/util.py +27 -1
- {ogc_na-0.3.43.dist-info → ogc_na-0.3.45.dist-info}/METADATA +1 -1
- {ogc_na-0.3.43.dist-info → ogc_na-0.3.45.dist-info}/RECORD +7 -7
- {ogc_na-0.3.43.dist-info → ogc_na-0.3.45.dist-info}/WHEEL +0 -0
- {ogc_na-0.3.43.dist-info → ogc_na-0.3.45.dist-info}/top_level.txt +0 -0
ogc/na/_version.py
CHANGED
ogc/na/annotate_schema.py
CHANGED
|
@@ -122,7 +122,6 @@ import json
|
|
|
122
122
|
import logging
|
|
123
123
|
import re
|
|
124
124
|
import sys
|
|
125
|
-
from collections import deque
|
|
126
125
|
from operator import attrgetter
|
|
127
126
|
from pathlib import Path
|
|
128
127
|
from typing import Any, AnyStr, Callable, Sequence, Iterable
|
|
@@ -131,7 +130,8 @@ from urllib.parse import urlparse, urljoin
|
|
|
131
130
|
import jsonschema
|
|
132
131
|
import requests_cache
|
|
133
132
|
|
|
134
|
-
from ogc.na.util import is_url, load_yaml, LRUCache, dump_yaml,
|
|
133
|
+
from ogc.na.util import is_url, load_yaml, LRUCache, dump_yaml, \
|
|
134
|
+
merge_contexts, merge_dicts, dict_contains, JSON_LD_KEYWORDS
|
|
135
135
|
|
|
136
136
|
logger = logging.getLogger(__name__)
|
|
137
137
|
|
|
@@ -146,6 +146,8 @@ ANNOTATION_IGNORE_EXPAND = [ANNOTATION_CONTEXT, ANNOTATION_EXTRA_TERMS, ANNOTATI
|
|
|
146
146
|
|
|
147
147
|
CURIE_TERMS = '@id', '@type', '@index'
|
|
148
148
|
|
|
149
|
+
UNDEFINED = object()
|
|
150
|
+
|
|
149
151
|
context_term_cache = LRUCache(maxsize=20)
|
|
150
152
|
requests_session = requests_cache.CachedSession('ogc.na.annotate_schema', backend='memory', expire_after=180)
|
|
151
153
|
|
|
@@ -340,12 +342,14 @@ def resolve_context(ctx: Path | str | dict | list, expand_uris=True) -> Resolved
|
|
|
340
342
|
prefixes = {}
|
|
341
343
|
|
|
342
344
|
def expand_uri(curie, ctx_stack):
|
|
343
|
-
if not expand_uris or not ctx_stack or not curie or curie
|
|
345
|
+
if not expand_uris or not ctx_stack or not curie or curie in JSON_LD_KEYWORDS:
|
|
344
346
|
return curie
|
|
345
347
|
if ':' in curie:
|
|
346
348
|
prefix, localpart = curie.split(':', 1)
|
|
347
349
|
else:
|
|
348
350
|
prefix, localpart = None, None
|
|
351
|
+
|
|
352
|
+
vocab = UNDEFINED
|
|
349
353
|
for c in reversed(ctx_stack):
|
|
350
354
|
if localpart:
|
|
351
355
|
# prefix:localpart format
|
|
@@ -354,9 +358,11 @@ def resolve_context(ctx: Path | str | dict | list, expand_uris=True) -> Resolved
|
|
|
354
358
|
prefix_uri = term_val if isinstance(term_val, str) else term_val.get('@id')
|
|
355
359
|
prefixes[prefix] = prefix_uri
|
|
356
360
|
return f"{prefix_uri}{localpart}"
|
|
357
|
-
elif '@vocab' in c:
|
|
358
|
-
# look for @vocab
|
|
359
|
-
|
|
361
|
+
elif '@vocab' in c and vocab is UNDEFINED:
|
|
362
|
+
# look for @vocab unless it has been overridden (e.g. set to null) somewhere down the chain
|
|
363
|
+
vocab = c['@vocab']
|
|
364
|
+
if isinstance(vocab, str):
|
|
365
|
+
return f"{c['@vocab']}{curie}"
|
|
360
366
|
|
|
361
367
|
return curie
|
|
362
368
|
|
|
@@ -388,7 +394,11 @@ def resolve_context(ctx: Path | str | dict | list, expand_uris=True) -> Resolved
|
|
|
388
394
|
resolved_ctx = {}
|
|
389
395
|
inner_prefixes = {}
|
|
390
396
|
for ctx_entry in inner_ctx:
|
|
391
|
-
|
|
397
|
+
if isinstance(ctx_entry, dict):
|
|
398
|
+
# Array entries must be wrapped with @context
|
|
399
|
+
resolved_entry = resolve_context({'@context': ctx_entry})
|
|
400
|
+
else:
|
|
401
|
+
resolved_entry = resolve_context(ctx_entry)
|
|
392
402
|
inner_prefixes.update(resolved_entry.prefixes)
|
|
393
403
|
resolved = ResolvedContext(merge_dicts(resolved_entry.context, resolved_ctx), inner_prefixes)
|
|
394
404
|
else:
|
|
@@ -481,26 +491,28 @@ class SchemaAnnotator:
|
|
|
481
491
|
updated_refs: set[int] = set()
|
|
482
492
|
|
|
483
493
|
def find_prop_context(prop, context_stack) -> dict | None:
|
|
494
|
+
vocab = UNDEFINED
|
|
484
495
|
for ctx in reversed(context_stack):
|
|
485
|
-
vocab
|
|
496
|
+
if vocab is UNDEFINED and '@vocab' in ctx:
|
|
497
|
+
vocab = ctx.get('@vocab')
|
|
486
498
|
if prop in ctx:
|
|
487
499
|
prop_ctx = ctx[prop]
|
|
488
500
|
if isinstance(prop_ctx, str):
|
|
489
|
-
if vocab and ':' not in prop_ctx and prop_ctx
|
|
501
|
+
if vocab and ':' not in prop_ctx and prop_ctx not in JSON_LD_KEYWORDS:
|
|
490
502
|
prop_ctx = f"{vocab}{prop_ctx}"
|
|
491
503
|
return {'@id': prop_ctx}
|
|
492
504
|
elif '@id' not in prop_ctx and not vocab:
|
|
493
505
|
raise ValueError(f'Missing @id for property {prop} in context {json.dumps(ctx, indent=2)}')
|
|
494
506
|
else:
|
|
495
|
-
result = {k: v for k, v in prop_ctx.items() if k
|
|
507
|
+
result = {k: v for k, v in prop_ctx.items() if k in JSON_LD_KEYWORDS}
|
|
496
508
|
if vocab:
|
|
497
509
|
prop_id = result.get('@id')
|
|
498
510
|
if not prop_id:
|
|
499
511
|
result['@id'] = f"{vocab}{prop}"
|
|
500
|
-
elif ':' not in prop_id and prop_id
|
|
512
|
+
elif ':' not in prop_id and prop_id not in JSON_LD_KEYWORDS:
|
|
501
513
|
result['@id'] = f"{vocab}{prop_id}"
|
|
502
514
|
return result
|
|
503
|
-
elif
|
|
515
|
+
elif isinstance(vocab, str):
|
|
504
516
|
return {'@id': f"{ctx['@vocab']}{prop}"}
|
|
505
517
|
|
|
506
518
|
def process_properties(obj: dict, context_stack: list[dict[str, Any]],
|
|
@@ -514,7 +526,7 @@ class SchemaAnnotator:
|
|
|
514
526
|
|
|
515
527
|
used_terms = set()
|
|
516
528
|
for prop in list(properties.keys()):
|
|
517
|
-
if prop
|
|
529
|
+
if prop in JSON_LD_KEYWORDS:
|
|
518
530
|
# skip JSON-LD keywords
|
|
519
531
|
continue
|
|
520
532
|
prop_value = properties[prop]
|
|
@@ -531,7 +543,7 @@ class SchemaAnnotator:
|
|
|
531
543
|
used_terms.add(prop)
|
|
532
544
|
prop_schema_ctx = {f"{ANNOTATION_PREFIX}{k[1:]}": v
|
|
533
545
|
for k, v in prop_ctx.items()
|
|
534
|
-
if k
|
|
546
|
+
if k in JSON_LD_KEYWORDS and k != '@context'}
|
|
535
547
|
prop_ctx_base = prop_ctx.get('@context', {}).get('@base')
|
|
536
548
|
if prop_ctx_base:
|
|
537
549
|
prop_schema_ctx[ANNOTATION_BASE] = prop_ctx_base
|
|
@@ -608,12 +620,14 @@ class SchemaAnnotator:
|
|
|
608
620
|
if len(context_stack) == level and context_stack[-1]:
|
|
609
621
|
extra_terms = {}
|
|
610
622
|
for k, v in context_stack[-1].items():
|
|
611
|
-
if k
|
|
623
|
+
if k not in JSON_LD_KEYWORDS and k not in prefixes and k not in used_terms:
|
|
612
624
|
if isinstance(v, dict):
|
|
613
625
|
if len(v) == 1 and '@id' in v:
|
|
614
626
|
v = v['@id']
|
|
615
627
|
else:
|
|
616
|
-
v = {f"{ANNOTATION_PREFIX}{vk[1:]}": vv
|
|
628
|
+
v = {f"{ANNOTATION_PREFIX}{vk[1:]}": vv
|
|
629
|
+
for vk, vv in v.items()
|
|
630
|
+
if vk in JSON_LD_KEYWORDS}
|
|
617
631
|
if isinstance(v, str) and v[-1] in ('#', '/', ':'):
|
|
618
632
|
prefixes[k] = v
|
|
619
633
|
else:
|
|
@@ -806,7 +820,7 @@ class ContextBuilder:
|
|
|
806
820
|
if compact:
|
|
807
821
|
|
|
808
822
|
def compact_uri(uri: str) -> str:
|
|
809
|
-
if uri
|
|
823
|
+
if uri in JSON_LD_KEYWORDS:
|
|
810
824
|
# JSON-LD keyword
|
|
811
825
|
return uri
|
|
812
826
|
|
|
@@ -821,7 +835,7 @@ class ContextBuilder:
|
|
|
821
835
|
|
|
822
836
|
def compact_branch(branch, context_stack=None) -> bool:
|
|
823
837
|
child_context_stack = context_stack + [branch] if context_stack else [branch]
|
|
824
|
-
terms = list(k for k in branch.keys() if k
|
|
838
|
+
terms = list(k for k in branch.keys() if k not in JSON_LD_KEYWORDS)
|
|
825
839
|
|
|
826
840
|
changed = False
|
|
827
841
|
for term in terms:
|
|
@@ -853,14 +867,15 @@ class ContextBuilder:
|
|
|
853
867
|
|
|
854
868
|
def compact_uris(branch, context_stack=None):
|
|
855
869
|
child_context_stack = context_stack + [branch] if context_stack else [branch]
|
|
856
|
-
terms = list(k for k in branch.keys() if k
|
|
870
|
+
terms = list(k for k in branch.keys() if k not in JSON_LD_KEYWORDS)
|
|
857
871
|
for term in terms:
|
|
858
872
|
term_value = branch.get(term)
|
|
859
873
|
if isinstance(term_value, str):
|
|
860
874
|
branch[term] = compact_uri(term_value)
|
|
861
875
|
elif isinstance(term_value, dict):
|
|
862
|
-
|
|
863
|
-
|
|
876
|
+
for k in CURIE_TERMS:
|
|
877
|
+
if k in term_value:
|
|
878
|
+
term_value[k] = compact_uri(term_value[k])
|
|
864
879
|
if len(term_value) == 1 and '@id' in term_value:
|
|
865
880
|
branch[term] = term_value['@id']
|
|
866
881
|
elif '@context' in term_value:
|
ogc/na/util.py
CHANGED
|
@@ -28,6 +28,32 @@ try:
|
|
|
28
28
|
except ImportError:
|
|
29
29
|
from yaml import Loader as YamlLoader, SafeLoader as SafeYamlLoader, Dumper as YamlDumper
|
|
30
30
|
|
|
31
|
+
JSON_LD_KEYWORDS = {
|
|
32
|
+
'@base',
|
|
33
|
+
'@container',
|
|
34
|
+
'@context',
|
|
35
|
+
'@direction',
|
|
36
|
+
'@graph',
|
|
37
|
+
'@id',
|
|
38
|
+
'@import',
|
|
39
|
+
'@included',
|
|
40
|
+
'@index',
|
|
41
|
+
'@json',
|
|
42
|
+
'@language',
|
|
43
|
+
'@list',
|
|
44
|
+
'@nest',
|
|
45
|
+
'@none',
|
|
46
|
+
'@prefix',
|
|
47
|
+
'@propagate',
|
|
48
|
+
'@protected',
|
|
49
|
+
'@reverse',
|
|
50
|
+
'@set',
|
|
51
|
+
'@type',
|
|
52
|
+
'@value',
|
|
53
|
+
'@version',
|
|
54
|
+
'@vocab'
|
|
55
|
+
}
|
|
56
|
+
|
|
31
57
|
|
|
32
58
|
class ContextMergeError(Exception):
|
|
33
59
|
pass
|
|
@@ -294,7 +320,7 @@ def merge_contexts(a: dict, b: dict, fix_nest=True) -> dict[str, Any]:
|
|
|
294
320
|
for term in list(a.keys()):
|
|
295
321
|
va = a[term]
|
|
296
322
|
vb = b.get(term)
|
|
297
|
-
if term
|
|
323
|
+
if term not in JSON_LD_KEYWORDS:
|
|
298
324
|
if isinstance(va, str):
|
|
299
325
|
va = {'@id': va}
|
|
300
326
|
a[term] = va
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: ogc_na
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.45
|
|
4
4
|
Summary: OGC Naming Authority tools
|
|
5
5
|
Author-email: Rob Atkinson <ratkinson@ogc.org>, Piotr Zaborowski <pzaborowski@ogc.org>, Alejandro Villar <avillar@ogc.org>
|
|
6
6
|
Project-URL: Homepage, https://github.com/opengeospatial/ogc-na-tools/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
ogc/na/__init__.py,sha256=uzcNiJ3uKFNJ1HBfKxIwgAy2HMUFsLAe5RkrUg8ncac,464
|
|
2
|
-
ogc/na/_version.py,sha256=
|
|
3
|
-
ogc/na/annotate_schema.py,sha256=
|
|
2
|
+
ogc/na/_version.py,sha256=94Zx_mr9eAoDR-QvqK5Ld0uUkeJswI5m5cnKSahrcV8,413
|
|
3
|
+
ogc/na/annotate_schema.py,sha256=IdVc3my8FkxvJwwmIGFu5RcyvyOK-dQjwLWh-NFrm4g,40367
|
|
4
4
|
ogc/na/domain_config.py,sha256=C6ao37dbXEKv_K7WcfzQgI3H1Hr3c4-3p24hgl2oH54,13896
|
|
5
5
|
ogc/na/download.py,sha256=2afrLyl4WsAlxkCgXsl47fs9mNKfDmhVpeT2iwNSoq0,3354
|
|
6
6
|
ogc/na/gsp.py,sha256=KGa2G9i8kPefYTHNPUDoXnNyF7Tiwt8K__Ew_Qa7eeg,6048
|
|
@@ -9,12 +9,12 @@ ogc/na/models.py,sha256=nGV8EALtXvmBtkUbu0FA4KOgwNUqQGWIDuMo7UGOKP8,652
|
|
|
9
9
|
ogc/na/profile.py,sha256=T7nesbm7azF2ijF60UenJnQQKjIgJlnJ3pUbGT5nYgM,16511
|
|
10
10
|
ogc/na/provenance.py,sha256=h7UtUb1wW_9MfEim0fjcqkHd0BYmpXqyE1ADzL9AH7I,5551
|
|
11
11
|
ogc/na/update_vocabs.py,sha256=joLZxhpBJja5GvaBnt0aHQStKETOCIh5PotUxmJsOHs,18180
|
|
12
|
-
ogc/na/util.py,sha256=
|
|
12
|
+
ogc/na/util.py,sha256=r-cwqxqVVH1oXWsWuobTvXFGUVCqwlalN97b85nUN4U,11951
|
|
13
13
|
ogc/na/validation.py,sha256=5xjHH55NZKM8HtUk8XgVzm8W5ZlZY00u_qsWfXK_8dM,3732
|
|
14
14
|
ogc/na/input_filters/__init__.py,sha256=AhE7n_yECwxFKwOM3Jc0ft96TtF5i_Z-fHrS4HYOjaE,1179
|
|
15
15
|
ogc/na/input_filters/csv.py,sha256=nFfB1XQF_QApcGGzMqEvzD_b3pBtCtsfUECsZ9UGE6s,2616
|
|
16
16
|
ogc/na/input_filters/xml.py,sha256=9qYjp_w5JLInFM48zB15IYH9eTafjp1Aqd_8kfuW3aA,2074
|
|
17
|
-
ogc_na-0.3.
|
|
18
|
-
ogc_na-0.3.
|
|
19
|
-
ogc_na-0.3.
|
|
20
|
-
ogc_na-0.3.
|
|
17
|
+
ogc_na-0.3.45.dist-info/METADATA,sha256=M64A21bqXChPrmV3fK6LfkXI9khRbLYtDTkC4xc2qv0,3796
|
|
18
|
+
ogc_na-0.3.45.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
19
|
+
ogc_na-0.3.45.dist-info/top_level.txt,sha256=Kvy3KhzcIhNPT4_nZuJCmS946ptRr_MDyU4IIhZJhCY,4
|
|
20
|
+
ogc_na-0.3.45.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|