dump-things-pyclient 0.1.0__tar.gz → 0.1.2__tar.gz
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.
- {dump_things_pyclient-0.1.0 → dump_things_pyclient-0.1.2}/PKG-INFO +3 -1
- dump_things_pyclient-0.1.2/dump_things_pyclient/commands/json2ttl.py +64 -0
- dump_things_pyclient-0.1.2/dump_things_pyclient/commands/post_records.py +59 -0
- {dump_things_pyclient-0.1.0 → dump_things_pyclient-0.1.2}/dump_things_pyclient/communicate.py +38 -7
- {dump_things_pyclient-0.1.0 → dump_things_pyclient-0.1.2}/dump_things_pyclient.egg-info/PKG-INFO +3 -1
- {dump_things_pyclient-0.1.0 → dump_things_pyclient-0.1.2}/dump_things_pyclient.egg-info/SOURCES.txt +2 -0
- {dump_things_pyclient-0.1.0 → dump_things_pyclient-0.1.2}/dump_things_pyclient.egg-info/entry_points.txt +2 -0
- dump_things_pyclient-0.1.2/dump_things_pyclient.egg-info/requires.txt +2 -0
- {dump_things_pyclient-0.1.0 → dump_things_pyclient-0.1.2}/pyproject.toml +7 -1
- dump_things_pyclient-0.1.0/dump_things_pyclient.egg-info/requires.txt +0 -1
- {dump_things_pyclient-0.1.0 → dump_things_pyclient-0.1.2}/README.md +0 -0
- {dump_things_pyclient-0.1.0 → dump_things_pyclient-0.1.2}/dump_things_pyclient/__init__.py +0 -0
- {dump_things_pyclient-0.1.0 → dump_things_pyclient-0.1.2}/dump_things_pyclient/commands/__init__.py +0 -0
- {dump_things_pyclient-0.1.0 → dump_things_pyclient-0.1.2}/dump_things_pyclient/commands/auto_curate.py +0 -0
- {dump_things_pyclient-0.1.0 → dump_things_pyclient-0.1.2}/dump_things_pyclient/commands/get_records.py +0 -0
- {dump_things_pyclient-0.1.0 → dump_things_pyclient-0.1.2}/dump_things_pyclient/commands/read_pages.py +0 -0
- {dump_things_pyclient-0.1.0 → dump_things_pyclient-0.1.2}/dump_things_pyclient.egg-info/dependency_links.txt +0 -0
- {dump_things_pyclient-0.1.0 → dump_things_pyclient-0.1.2}/dump_things_pyclient.egg-info/top_level.txt +0 -0
- {dump_things_pyclient-0.1.0 → dump_things_pyclient-0.1.2}/setup.cfg +0 -0
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dump-things-pyclient
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
4
4
|
Summary: A client library and some CLI command for dump-things-services
|
|
5
|
+
Author-email: Christian Mönch <christian.moench@web.de>
|
|
5
6
|
Requires-Python: >=3.11
|
|
6
7
|
Description-Content-Type: text/markdown
|
|
8
|
+
Requires-Dist: dump-things-service>=5.3.0
|
|
7
9
|
Requires-Dist: requests>=2.32.5
|
|
8
10
|
|
|
9
11
|
# Dump Things Python Client
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
import json
|
|
5
|
+
import re
|
|
6
|
+
import sys
|
|
7
|
+
|
|
8
|
+
from dump_things_service.converter import (
|
|
9
|
+
Format,
|
|
10
|
+
FormatConverter,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
description = f"""Read JSON records from stdin and convert them to TTL
|
|
15
|
+
|
|
16
|
+
This command reads one record per line, either JSON format or a JSON-string
|
|
17
|
+
with a TTL-document from stdin, converts them to TTL or JSON and prints them
|
|
18
|
+
to stdout.
|
|
19
|
+
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def main():
|
|
24
|
+
argument_parser = argparse.ArgumentParser(
|
|
25
|
+
description=description,
|
|
26
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
27
|
+
)
|
|
28
|
+
argument_parser.add_argument('schema', help='URL of the schema that should be used')
|
|
29
|
+
|
|
30
|
+
arguments = argument_parser.parse_args()
|
|
31
|
+
|
|
32
|
+
print(f'Creating converter for schema {arguments.schema} ...', file=sys.stderr, end='', flush=True)
|
|
33
|
+
converter = FormatConverter(
|
|
34
|
+
arguments.schema,
|
|
35
|
+
input_format=Format.json,
|
|
36
|
+
output_format=Format.ttl,
|
|
37
|
+
)
|
|
38
|
+
print(' done', file=sys.stderr, flush=True)
|
|
39
|
+
|
|
40
|
+
error = False
|
|
41
|
+
for line in sys.stdin:
|
|
42
|
+
json_object = json.loads(line)
|
|
43
|
+
|
|
44
|
+
object_class = json_object.get('schema_type')
|
|
45
|
+
if object_class is None:
|
|
46
|
+
error = True
|
|
47
|
+
print(f'ERROR: No schema_type in {json_object}', file=sys.stderr, flush=True)
|
|
48
|
+
continue
|
|
49
|
+
|
|
50
|
+
class_name = re.search('([_A-Za-z0-9]*$)', object_class).group(0)
|
|
51
|
+
|
|
52
|
+
try:
|
|
53
|
+
ttl = converter.convert(json_object, class_name)
|
|
54
|
+
except ValueError as ve:
|
|
55
|
+
print(f'ERROR: conversion failed for {json_object}: {ve}', file=sys.stderr, flush=True)
|
|
56
|
+
continue
|
|
57
|
+
|
|
58
|
+
print(json.dumps(ttl))
|
|
59
|
+
|
|
60
|
+
return 1 if error else 0
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
if __name__ == '__main__':
|
|
64
|
+
sys.exit(main())
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
import json
|
|
5
|
+
import os
|
|
6
|
+
import sys
|
|
7
|
+
|
|
8
|
+
from ..communicate import (
|
|
9
|
+
collection_write_record,
|
|
10
|
+
curated_write_record,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def main():
|
|
15
|
+
argument_parser = argparse.ArgumentParser()
|
|
16
|
+
argument_parser.add_argument('base_url')
|
|
17
|
+
argument_parser.add_argument('collection')
|
|
18
|
+
argument_parser.add_argument('cls', metavar='class')
|
|
19
|
+
argument_parser.add_argument('--curated', action='store_true', help='bypass inbox, requires curator token')
|
|
20
|
+
|
|
21
|
+
arguments = argument_parser.parse_args()
|
|
22
|
+
|
|
23
|
+
token = os.environ.get('DUMPTHINGS_TOKEN')
|
|
24
|
+
if token is None:
|
|
25
|
+
print(
|
|
26
|
+
'WARNING: environment variable DUMPTHINGS_TOKEN not set',
|
|
27
|
+
file=sys.stderr,
|
|
28
|
+
flush=True,
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
if arguments.curated:
|
|
32
|
+
write_record = curated_write_record
|
|
33
|
+
else:
|
|
34
|
+
write_record = collection_write_record
|
|
35
|
+
|
|
36
|
+
posted = False
|
|
37
|
+
for line in sys.stdin:
|
|
38
|
+
record = json.loads(line)
|
|
39
|
+
try:
|
|
40
|
+
write_record(
|
|
41
|
+
service_url=arguments.base_url,
|
|
42
|
+
collection=arguments.collection,
|
|
43
|
+
class_name=arguments.cls,
|
|
44
|
+
record=record,
|
|
45
|
+
token=token,
|
|
46
|
+
)
|
|
47
|
+
except Exception as e:
|
|
48
|
+
print(f'Error: {e}', file=sys.stderr, flush=True)
|
|
49
|
+
else:
|
|
50
|
+
posted = True
|
|
51
|
+
print('.', end='', flush=True)
|
|
52
|
+
|
|
53
|
+
if posted:
|
|
54
|
+
# final newline
|
|
55
|
+
print('')
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
if __name__ == '__main__':
|
|
59
|
+
sys.exit(main())
|
{dump_things_pyclient-0.1.0 → dump_things_pyclient-0.1.2}/dump_things_pyclient/communicate.py
RENAMED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import logging
|
|
4
|
+
import re
|
|
4
5
|
from itertools import count
|
|
5
6
|
from typing import (
|
|
6
7
|
Callable,
|
|
@@ -18,6 +19,7 @@ __all__ = [
|
|
|
18
19
|
'JSON',
|
|
19
20
|
'get_paginated',
|
|
20
21
|
'get',
|
|
22
|
+
'collection_get_classes',
|
|
21
23
|
'collection_delete_record',
|
|
22
24
|
'collection_read_records',
|
|
23
25
|
'collection_read_records_of_class',
|
|
@@ -99,6 +101,29 @@ def get(url: str,
|
|
|
99
101
|
return _get_from_url(url, token, parameters)
|
|
100
102
|
|
|
101
103
|
|
|
104
|
+
def collection_get_classes(service_url: str,
|
|
105
|
+
collection: str,
|
|
106
|
+
) -> Generator[str, None, None]:
|
|
107
|
+
"""Read classes that are supported by the collection
|
|
108
|
+
|
|
109
|
+
Get the name of the classes that are known in the collection. If the
|
|
110
|
+
collection does not exist on the server, no class names are returned.
|
|
111
|
+
|
|
112
|
+
:param service_url: the base URL of the service, i.e., the URL up to
|
|
113
|
+
`/<collection>/...` or `/server`
|
|
114
|
+
:param collection: the name of the collection
|
|
115
|
+
|
|
116
|
+
:return: a generator yielding names of the supported classes
|
|
117
|
+
"""
|
|
118
|
+
service_url = f'{service_url[:-1]}' if service_url.endswith('/') else service_url
|
|
119
|
+
matcher = re.compile(f'/{collection}/record/([A-Z][_a-zA-Z0-9]*)$')
|
|
120
|
+
open_api_spec = _get_from_url(service_url + '/openapi.json', None)
|
|
121
|
+
for path in open_api_spec['paths']:
|
|
122
|
+
match = matcher.match(path)
|
|
123
|
+
if match:
|
|
124
|
+
yield match.group(1)
|
|
125
|
+
|
|
126
|
+
|
|
102
127
|
def collection_read_record_with_pid(service_url: str,
|
|
103
128
|
collection: str,
|
|
104
129
|
pid: str,
|
|
@@ -236,11 +261,12 @@ def collection_write_record(
|
|
|
236
261
|
than one record due to inlined-relations extraction. The individual
|
|
237
262
|
records might have annotations added
|
|
238
263
|
"""
|
|
264
|
+
_check_format_value(format)
|
|
239
265
|
return _post_to_url(
|
|
240
266
|
url=_build_url(service_url, collection, f'record/{class_name}'),
|
|
241
267
|
token=token,
|
|
242
|
-
|
|
243
|
-
|
|
268
|
+
params={'format': format},
|
|
269
|
+
**(dict(json=record) if format == 'json' else dict(data=record)))
|
|
244
270
|
|
|
245
271
|
|
|
246
272
|
def collection_validate_record(
|
|
@@ -269,12 +295,12 @@ def collection_validate_record(
|
|
|
269
295
|
|
|
270
296
|
:return: True
|
|
271
297
|
"""
|
|
272
|
-
|
|
298
|
+
_check_format_value(format)
|
|
273
299
|
return _post_to_url(
|
|
274
300
|
url=_build_url(service_url, collection, f'validate/{class_name}'),
|
|
275
301
|
token=token,
|
|
276
|
-
|
|
277
|
-
|
|
302
|
+
params={'format': format},
|
|
303
|
+
**(dict(json=record) if format == 'json' else dict(data=record)))
|
|
278
304
|
|
|
279
305
|
|
|
280
306
|
def collection_delete_record(
|
|
@@ -660,10 +686,10 @@ def _get_from_url(url: str,
|
|
|
660
686
|
|
|
661
687
|
def _post_to_url(url: str,
|
|
662
688
|
token: str | None,
|
|
663
|
-
json: JSON,
|
|
664
689
|
params: dict[str, str] | None = None,
|
|
690
|
+
**kwargs,
|
|
665
691
|
) -> JSON:
|
|
666
|
-
return _do_request(requests.post, url, token, params,
|
|
692
|
+
return _do_request(requests.post, url, token, params, **kwargs)
|
|
667
693
|
|
|
668
694
|
|
|
669
695
|
def _delete_url(url: str,
|
|
@@ -717,3 +743,8 @@ def _get_page(url_base: str,
|
|
|
717
743
|
parameters['page'] = first_page
|
|
718
744
|
parameters['size'] = page_size
|
|
719
745
|
return _get_from_url(url_base, token, parameters)
|
|
746
|
+
|
|
747
|
+
|
|
748
|
+
def _check_format_value(format: str) -> None:
|
|
749
|
+
if format not in ('json', 'ttl'):
|
|
750
|
+
raise ValueError('Format must be either "json" or "ttl"')
|
{dump_things_pyclient-0.1.0 → dump_things_pyclient-0.1.2}/dump_things_pyclient.egg-info/PKG-INFO
RENAMED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dump-things-pyclient
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
4
4
|
Summary: A client library and some CLI command for dump-things-services
|
|
5
|
+
Author-email: Christian Mönch <christian.moench@web.de>
|
|
5
6
|
Requires-Python: >=3.11
|
|
6
7
|
Description-Content-Type: text/markdown
|
|
8
|
+
Requires-Dist: dump-things-service>=5.3.0
|
|
7
9
|
Requires-Dist: requests>=2.32.5
|
|
8
10
|
|
|
9
11
|
# Dump Things Python Client
|
{dump_things_pyclient-0.1.0 → dump_things_pyclient-0.1.2}/dump_things_pyclient.egg-info/SOURCES.txt
RENAMED
|
@@ -11,4 +11,6 @@ dump_things_pyclient.egg-info/top_level.txt
|
|
|
11
11
|
dump_things_pyclient/commands/__init__.py
|
|
12
12
|
dump_things_pyclient/commands/auto_curate.py
|
|
13
13
|
dump_things_pyclient/commands/get_records.py
|
|
14
|
+
dump_things_pyclient/commands/json2ttl.py
|
|
15
|
+
dump_things_pyclient/commands/post_records.py
|
|
14
16
|
dump_things_pyclient/commands/read_pages.py
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
[console_scripts]
|
|
2
2
|
auto-curate = dump_things_pyclient.commands.auto_curate:main
|
|
3
3
|
get-records = dump_things_pyclient.commands.get_records:main
|
|
4
|
+
json2ttl = dump_things_pyclient.commands.json2ttl:main
|
|
5
|
+
post-records = dump_things_pyclient.commands.post_records:main
|
|
4
6
|
read-pages = dump_things_pyclient.commands.read_pages:main
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "dump-things-pyclient"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.2"
|
|
4
4
|
description = "A client library and some CLI command for dump-things-services"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.11"
|
|
7
|
+
authors = [
|
|
8
|
+
{name="Christian Mönch", email="christian.moench@web.de"},
|
|
9
|
+
]
|
|
7
10
|
dependencies = [
|
|
11
|
+
"dump-things-service>=5.3.0",
|
|
8
12
|
"requests>=2.32.5",
|
|
9
13
|
]
|
|
10
14
|
|
|
@@ -17,3 +21,5 @@ tests = [
|
|
|
17
21
|
auto-curate = "dump_things_pyclient.commands.auto_curate:main"
|
|
18
22
|
read-pages = "dump_things_pyclient.commands.read_pages:main"
|
|
19
23
|
get-records = "dump_things_pyclient.commands.get_records:main"
|
|
24
|
+
json2ttl = "dump_things_pyclient.commands.json2ttl:main"
|
|
25
|
+
post-records = "dump_things_pyclient.commands.post_records:main"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
requests>=2.32.5
|
|
File without changes
|
|
File without changes
|
{dump_things_pyclient-0.1.0 → dump_things_pyclient-0.1.2}/dump_things_pyclient/commands/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|