clams-python 1.1.0__tar.gz → 1.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.
- {clams-python-1.1.0/clams_python.egg-info → clams-python-1.1.2}/PKG-INFO +7 -6
- {clams-python-1.1.0 → clams-python-1.1.2}/README.md +5 -4
- clams-python-1.1.2/VERSION +1 -0
- {clams-python-1.1.0 → clams-python-1.1.2}/clams/app/__init__.py +3 -6
- {clams-python-1.1.0 → clams-python-1.1.2}/clams/appmetadata/__init__.py +6 -6
- {clams-python-1.1.0 → clams-python-1.1.2}/clams/mmif_utils/rewind.py +28 -38
- {clams-python-1.1.0 → clams-python-1.1.2}/clams/restify/__init__.py +7 -4
- clams-python-1.1.2/clams/ver/__init__.py +1 -0
- {clams-python-1.1.0 → clams-python-1.1.2/clams_python.egg-info}/PKG-INFO +7 -6
- {clams-python-1.1.0 → clams-python-1.1.2}/clams_python.egg-info/requires.txt +1 -1
- {clams-python-1.1.0 → clams-python-1.1.2}/requirements.txt +1 -1
- {clams-python-1.1.0 → clams-python-1.1.2}/tests/test_clamsapp.py +17 -6
- clams-python-1.1.0/VERSION +0 -1
- clams-python-1.1.0/clams/ver/__init__.py +0 -1
- {clams-python-1.1.0 → clams-python-1.1.2}/LICENSE +0 -0
- {clams-python-1.1.0 → clams-python-1.1.2}/MANIFEST.in +0 -0
- {clams-python-1.1.0 → clams-python-1.1.2}/clams/__init__.py +0 -0
- {clams-python-1.1.0 → clams-python-1.1.2}/clams/develop/__init__.py +0 -0
- {clams-python-1.1.0 → clams-python-1.1.2}/clams/develop/templates/app/.dockerignore.template +0 -0
- {clams-python-1.1.0 → clams-python-1.1.2}/clams/develop/templates/app/.gitignore.template +0 -0
- {clams-python-1.1.0 → clams-python-1.1.2}/clams/develop/templates/app/Containerfile.template +0 -0
- {clams-python-1.1.0 → clams-python-1.1.2}/clams/develop/templates/app/LICENSE.template +0 -0
- {clams-python-1.1.0 → clams-python-1.1.2}/clams/develop/templates/app/README.md.template +0 -0
- {clams-python-1.1.0 → clams-python-1.1.2}/clams/develop/templates/app/app.py.template +0 -0
- {clams-python-1.1.0 → clams-python-1.1.2}/clams/develop/templates/app/metadata.py.template +0 -0
- {clams-python-1.1.0 → clams-python-1.1.2}/clams/develop/templates/app/requirements.txt.template +0 -0
- {clams-python-1.1.0 → clams-python-1.1.2}/clams/develop/templates/gha/for-clams-team.md.template +0 -0
- {clams-python-1.1.0 → clams-python-1.1.2}/clams/develop/templates/gha/workflows/issue-apps-project.yml.template +0 -0
- {clams-python-1.1.0 → clams-python-1.1.2}/clams/develop/templates/gha/workflows/issue-assign.yml.template +0 -0
- {clams-python-1.1.0 → clams-python-1.1.2}/clams/develop/templates/gha/workflows/issue-close.yml.template +0 -0
- {clams-python-1.1.0 → clams-python-1.1.2}/clams/develop/templates/gha/workflows/publish.yml.template +0 -0
- {clams-python-1.1.0 → clams-python-1.1.2}/clams/mmif_utils/__init__.py +0 -0
- {clams-python-1.1.0 → clams-python-1.1.2}/clams/mmif_utils/source.py +0 -0
- {clams-python-1.1.0 → clams-python-1.1.2}/clams/serve/__init__.py +0 -0
- {clams-python-1.1.0 → clams-python-1.1.2}/clams_python.egg-info/SOURCES.txt +0 -0
- {clams-python-1.1.0 → clams-python-1.1.2}/clams_python.egg-info/dependency_links.txt +0 -0
- {clams-python-1.1.0 → clams-python-1.1.2}/clams_python.egg-info/entry_points.txt +0 -0
- {clams-python-1.1.0 → clams-python-1.1.2}/clams_python.egg-info/top_level.txt +0 -0
- {clams-python-1.1.0 → clams-python-1.1.2}/setup.cfg +0 -0
- {clams-python-1.1.0 → clams-python-1.1.2}/setup.py +0 -0
- {clams-python-1.1.0 → clams-python-1.1.2}/tests/test_clamscli.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: clams-python
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.2
|
|
4
4
|
Summary: A collection of APIs to develop CLAMS app for python
|
|
5
5
|
Home-page: https://clams.ai
|
|
6
6
|
Author: Brandeis Lab for Linguistics and Computation
|
|
@@ -14,7 +14,7 @@ Classifier: Programming Language :: Python :: 3 :: Only
|
|
|
14
14
|
Requires-Python: >=3.8
|
|
15
15
|
Description-Content-Type: text/markdown
|
|
16
16
|
License-File: LICENSE
|
|
17
|
-
Requires-Dist: mmif-python==1.0.
|
|
17
|
+
Requires-Dist: mmif-python==1.0.9
|
|
18
18
|
Requires-Dist: Flask>=2
|
|
19
19
|
Requires-Dist: Flask-RESTful>=0.3.9
|
|
20
20
|
Requires-Dist: gunicorn>=20
|
|
@@ -33,9 +33,10 @@ Requires-Dist: jsonschema>=3
|
|
|
33
33
|
1. a flask-based wrapper to run a Python CLAMS app as an HTTP web app
|
|
34
34
|
1. cookie-cutter shell command that sets up everything and starts a new CLAMS app project
|
|
35
35
|
|
|
36
|
-
### Start now from [Getting Started](introduction.html)!
|
|
36
|
+
### Start now from [Getting Started](https://clamsproject.github.io/clams-python/introduction.html)!
|
|
37
37
|
|
|
38
38
|
## For more ...
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
* [Version history and patch notes](https://github.com/clamsproject/clams-python/blob/main/CHANGELOG.md)
|
|
40
|
+
* [CLAMS Python API documentation](https://clamsproject.github.io/clams-python/modules.html)
|
|
41
|
+
* [MMIF-specific Python API documentation](https://clamsproject.github.io/mmif-python)
|
|
42
|
+
* [Public CLAMS App Directory](https://clamsproject.github.io/apps)
|
|
@@ -9,9 +9,10 @@
|
|
|
9
9
|
1. a flask-based wrapper to run a Python CLAMS app as an HTTP web app
|
|
10
10
|
1. cookie-cutter shell command that sets up everything and starts a new CLAMS app project
|
|
11
11
|
|
|
12
|
-
### Start now from [Getting Started](introduction.html)!
|
|
12
|
+
### Start now from [Getting Started](https://clamsproject.github.io/clams-python/introduction.html)!
|
|
13
13
|
|
|
14
14
|
## For more ...
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
* [Version history and patch notes](https://github.com/clamsproject/clams-python/blob/main/CHANGELOG.md)
|
|
16
|
+
* [CLAMS Python API documentation](https://clamsproject.github.io/clams-python/modules.html)
|
|
17
|
+
* [MMIF-specific Python API documentation](https://clamsproject.github.io/mmif-python)
|
|
18
|
+
* [Public CLAMS App Directory](https://clamsproject.github.io/apps)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
1.1.2
|
|
@@ -137,7 +137,6 @@ class ClamsApp(ABC):
|
|
|
137
137
|
|
|
138
138
|
#. Create a new view (or views) by calling :meth:`~mmif.serialize.mmif.Mmif.new_view` on the input mmif object.
|
|
139
139
|
#. Call :meth:`~clams.app.ClamsApp.sign_view` with the input runtime parameters for the record.
|
|
140
|
-
#. Call :meth:`~clams.app.ClamsApp.get_configuration` to get an "upgraded" runtime parameters with default values.
|
|
141
140
|
#. Call :meth:`~mmif.serialize.view.View.new_contain` on the new view object with any annotation properties specified by the configuration.
|
|
142
141
|
#. Process the data and create :class:`~mmif.serialize.annotation.Annotation` objects and add them to the new view.
|
|
143
142
|
#. While doing so, get help from :class:`~mmif.vocabulary.document_types.DocumentTypes`, :class:`~mmif.vocabulary.annotation_types.AnnotationTypes` classes to generate ``@type`` strings.
|
|
@@ -177,7 +176,7 @@ class ClamsApp(ABC):
|
|
|
177
176
|
def get_configuration(self, **runtime_params):
|
|
178
177
|
warnings.warn("ClamsApp.get_configuration() is deprecated. "
|
|
179
178
|
"If you are using this method in `_annotate()` method,"
|
|
180
|
-
"it is no longer needed since `clams-python
|
|
179
|
+
"it is no longer needed since `clams-python>1.0.9`.",
|
|
181
180
|
DeprecationWarning, stacklevel=2)
|
|
182
181
|
return self._refine_params(**runtime_params)
|
|
183
182
|
|
|
@@ -195,8 +194,8 @@ class ClamsApp(ABC):
|
|
|
195
194
|
# TODO (krim @ 8/2/23): once all devs understood this change, make runtime_conf a required argument
|
|
196
195
|
if runtime_conf is None:
|
|
197
196
|
warnings.warn("`runtime_conf` argument for ClamsApp.sign_view() will "
|
|
198
|
-
"no longer be optional in the future. Please
|
|
199
|
-
"
|
|
197
|
+
"no longer be optional in the future. Please pass `runtime_params` "
|
|
198
|
+
"from _annotate() method.",
|
|
200
199
|
FutureWarning, stacklevel=2)
|
|
201
200
|
view.metadata.app = self.metadata.identifier
|
|
202
201
|
if runtime_conf is not None:
|
|
@@ -205,8 +204,6 @@ class ClamsApp(ABC):
|
|
|
205
204
|
else:
|
|
206
205
|
conf = runtime_conf
|
|
207
206
|
view.metadata.add_parameters(**{k: str(v) for k, v in conf.items()})
|
|
208
|
-
# TODO (krim @ 8/2/23): add "refined" parameters as well
|
|
209
|
-
# once https://github.com/clamsproject/mmif/issues/208 is resolved
|
|
210
207
|
|
|
211
208
|
def set_error_view(self, mmif: Union[str, dict, Mmif], runtime_conf: Optional[dict] = None) -> Mmif:
|
|
212
209
|
"""
|
|
@@ -12,7 +12,7 @@ from mmif import vocabulary
|
|
|
12
12
|
unresolved_app_version_num = 'unresolvable'
|
|
13
13
|
app_version_envvar_key = 'CLAMS_APP_VERSION'
|
|
14
14
|
# type aliases to use in app metadata and runtime parameter processing
|
|
15
|
-
|
|
15
|
+
real_valued_primitives = Union[int, float, bool, str]
|
|
16
16
|
# these names are taken from the JSON schema data types
|
|
17
17
|
param_value_types = Literal['integer', 'number', 'string', 'boolean']
|
|
18
18
|
|
|
@@ -69,7 +69,7 @@ class Output(_BaseModel):
|
|
|
69
69
|
alias="@type",
|
|
70
70
|
description="The type of the object. Must be a IRI string."
|
|
71
71
|
)
|
|
72
|
-
properties: Dict[str,
|
|
72
|
+
properties: Dict[str, real_valued_primitives] = pydantic.Field(
|
|
73
73
|
{},
|
|
74
74
|
description="(optional) Specification for type properties, if any."
|
|
75
75
|
)
|
|
@@ -126,11 +126,11 @@ class RuntimeParameter(_BaseModel):
|
|
|
126
126
|
...,
|
|
127
127
|
description=f"Type of the parameter value the app expects. Must be one of {param_value_types_values}."
|
|
128
128
|
)
|
|
129
|
-
choices: List[
|
|
129
|
+
choices: List[real_valued_primitives] = pydantic.Field(
|
|
130
130
|
None,
|
|
131
131
|
description="(optional) List of string values that can be accepted."
|
|
132
132
|
)
|
|
133
|
-
default:
|
|
133
|
+
default: real_valued_primitives = pydantic.Field(
|
|
134
134
|
None,
|
|
135
135
|
description="(optional) Default value for the parameter. Only valid for optional parameters. Namely, setting "
|
|
136
136
|
"a default value makes a parameter 'optional'."
|
|
@@ -344,9 +344,9 @@ class AppMetadata(pydantic.BaseModel):
|
|
|
344
344
|
raise ValueError(f"Cannot add a duplicate output '{new}'.")
|
|
345
345
|
|
|
346
346
|
def add_parameter(self, name: str, description: str, type: param_value_types,
|
|
347
|
-
choices: Optional[List[
|
|
347
|
+
choices: Optional[List[real_valued_primitives]] = None,
|
|
348
348
|
multivalued: bool = False,
|
|
349
|
-
default:
|
|
349
|
+
default: real_valued_primitives = None):
|
|
350
350
|
"""
|
|
351
351
|
Helper method to add an element to the ``parameters`` list.
|
|
352
352
|
"""
|
|
@@ -6,44 +6,27 @@ from pathlib import Path as P
|
|
|
6
6
|
import mmif
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
def
|
|
10
|
-
try:
|
|
11
|
-
ichoice = int(choice)
|
|
12
|
-
if 0 <= ichoice:
|
|
13
|
-
return ichoice
|
|
14
|
-
else:
|
|
15
|
-
raise ValueError(f"\nInvalid argument for -n. Please enter a positive integer.")
|
|
16
|
-
except ValueError:
|
|
17
|
-
raise argparse.ArgumentTypeError(f"\nInvalid argument for -n. Please enter a positive integer.")
|
|
18
|
-
|
|
19
|
-
def user_choice(mmif_obj:mmif.Mmif) -> int:
|
|
9
|
+
def prompt_user(mmif_obj: mmif.Mmif) -> int:
|
|
20
10
|
"""
|
|
21
11
|
Function to ask user to choose the rewind range.
|
|
22
|
-
|
|
23
|
-
:param mmif_obj: mmif object
|
|
24
|
-
:return: int option number
|
|
25
12
|
"""
|
|
26
13
|
|
|
27
14
|
## Give a user options (#, "app", "timestamp") - time order
|
|
28
15
|
n = len(mmif_obj.views)
|
|
29
16
|
i = 0 # option number
|
|
17
|
+
aname = ""
|
|
18
|
+
a = 0
|
|
30
19
|
# header
|
|
31
|
-
print("\n" + "{:<
|
|
32
|
-
for view in mmif_obj.views:
|
|
33
|
-
|
|
34
|
-
|
|
20
|
+
print("\n" + "{:<8} {:<8} {:<30} {:<100}".format("view-num", "app-num", "timestamp", "app"))
|
|
21
|
+
for view in reversed(mmif_obj.views):
|
|
22
|
+
if view.metadata.app != aname:
|
|
23
|
+
aname = view.metadata.app
|
|
24
|
+
a += 1
|
|
35
25
|
i += 1
|
|
26
|
+
print("{:<8} {:<8} {:<30} {:<100}".format(i, a, str(view.metadata.timestamp), str(view.metadata.app)))
|
|
36
27
|
|
|
37
28
|
## User input
|
|
38
|
-
|
|
39
|
-
choice = int(input("\nEnter the number to delete from that point by rewinding: "))
|
|
40
|
-
try:
|
|
41
|
-
if 0 <= choice <= n:
|
|
42
|
-
return choice
|
|
43
|
-
else:
|
|
44
|
-
print(f"\nInvalid choice. Please enter an integer in the range [0, {n}].")
|
|
45
|
-
except ValueError:
|
|
46
|
-
print("\nInvalid input. Please enter a valid number.")
|
|
29
|
+
return int(input("\nEnter the number to delete from that point by rewinding: "))
|
|
47
30
|
|
|
48
31
|
|
|
49
32
|
def rewind_mmif(mmif_obj: mmif.Mmif, choice: int, choice_is_viewnum: bool = True) -> mmif.Mmif:
|
|
@@ -92,24 +75,32 @@ def describe_argparser():
|
|
|
92
75
|
|
|
93
76
|
|
|
94
77
|
def prep_argparser(**kwargs):
|
|
95
|
-
parser = argparse.ArgumentParser(description=describe_argparser()[1],
|
|
96
|
-
|
|
97
|
-
parser.add_argument("
|
|
98
|
-
|
|
99
|
-
parser.add_argument("-
|
|
100
|
-
|
|
78
|
+
parser = argparse.ArgumentParser(description=describe_argparser()[1],
|
|
79
|
+
formatter_class=argparse.RawDescriptionHelpFormatter, **kwargs)
|
|
80
|
+
parser.add_argument("mmif_file",
|
|
81
|
+
help="Path to the input MMIF file, or '-' to read from stdin.")
|
|
82
|
+
parser.add_argument("-o", '--output', default=None, metavar="PATH",
|
|
83
|
+
help="Path to the rewound MMIF output file. When not given, the rewound is printed to stdout.")
|
|
84
|
+
parser.add_argument("-p", '--pretty', action='store_true',
|
|
85
|
+
help="Pretty-print rewound MMIF")
|
|
86
|
+
parser.add_argument("-n", '--number', default="0", type=int,
|
|
87
|
+
help="Number of views or apps to rewind, must be a positive integer. "
|
|
88
|
+
"If 0, the user will be prompted to choose. (default: 0)")
|
|
89
|
+
parser.add_argument("-m", '--mode', choices=['app', 'view'], default='view',
|
|
90
|
+
help="Choose to rewind by number of views or number of producer apps. (default: view)")
|
|
101
91
|
return parser
|
|
102
92
|
|
|
103
93
|
|
|
104
94
|
def main(args):
|
|
105
|
-
mmif_obj = mmif.Mmif(sys.stdin) if args.mmif_file[0] == '-' else mmif.Mmif(open(args.mmif_file
|
|
95
|
+
mmif_obj = mmif.Mmif(str(sys.stdin)) if args.mmif_file[0] == '-' else mmif.Mmif(open(args.mmif_file).read())
|
|
106
96
|
|
|
107
|
-
if args.number == 0:
|
|
108
|
-
choice =
|
|
97
|
+
if args.number == 0: # If user doesn't know how many views to rewind, give them choices.
|
|
98
|
+
choice = prompt_user(mmif_obj)
|
|
109
99
|
else:
|
|
110
100
|
choice = args.number
|
|
101
|
+
if not isinstance(choice, int) or choice <= 0:
|
|
102
|
+
raise ValueError(f"Only can rewind by a positive number of views. Got {choice}.")
|
|
111
103
|
|
|
112
|
-
|
|
113
104
|
if args.output:
|
|
114
105
|
# Check if the same file name exist in the path and avoid overwriting.
|
|
115
106
|
output_fp = P(args.output)
|
|
@@ -132,4 +123,3 @@ if __name__ == "__main__":
|
|
|
132
123
|
parser = prep_argparser()
|
|
133
124
|
args = parser.parse_args()
|
|
134
125
|
main(args)
|
|
135
|
-
|
|
@@ -6,7 +6,7 @@ from flask_restful import Resource, Api
|
|
|
6
6
|
from mmif import Mmif
|
|
7
7
|
|
|
8
8
|
from clams.app import ClamsApp
|
|
9
|
-
from clams.appmetadata import
|
|
9
|
+
from clams.appmetadata import real_valued_primitives
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
class Restifier(object):
|
|
@@ -160,10 +160,10 @@ class ParameterCaster(object):
|
|
|
160
160
|
|
|
161
161
|
:param param_spec: A specification of a data types of parameters
|
|
162
162
|
"""
|
|
163
|
-
def __init__(self, param_spec: Dict[str, Tuple[
|
|
163
|
+
def __init__(self, param_spec: Dict[str, Tuple[real_valued_primitives, bool]]):
|
|
164
164
|
self.param_spec = param_spec
|
|
165
165
|
|
|
166
|
-
def cast(self, args: Dict[str, List[str]]) -> Dict[str, Union[
|
|
166
|
+
def cast(self, args: Dict[str, List[str]]) -> Dict[str, Union[real_valued_primitives, List[real_valued_primitives]]]:
|
|
167
167
|
"""
|
|
168
168
|
Given parameter specification, tries to cast values of args to specified Python data types.
|
|
169
169
|
Note that this caster deals with query strings, thus all keys and values in the input args are plain strings.
|
|
@@ -194,7 +194,10 @@ class ParameterCaster(object):
|
|
|
194
194
|
else:
|
|
195
195
|
casted[k] = v
|
|
196
196
|
else:
|
|
197
|
-
|
|
197
|
+
if len(vs) > 1:
|
|
198
|
+
casted[k] = vs
|
|
199
|
+
else:
|
|
200
|
+
casted[k] = vs[0]
|
|
198
201
|
|
|
199
202
|
return casted
|
|
200
203
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "1.1.2"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: clams-python
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.2
|
|
4
4
|
Summary: A collection of APIs to develop CLAMS app for python
|
|
5
5
|
Home-page: https://clams.ai
|
|
6
6
|
Author: Brandeis Lab for Linguistics and Computation
|
|
@@ -14,7 +14,7 @@ Classifier: Programming Language :: Python :: 3 :: Only
|
|
|
14
14
|
Requires-Python: >=3.8
|
|
15
15
|
Description-Content-Type: text/markdown
|
|
16
16
|
License-File: LICENSE
|
|
17
|
-
Requires-Dist: mmif-python==1.0.
|
|
17
|
+
Requires-Dist: mmif-python==1.0.9
|
|
18
18
|
Requires-Dist: Flask>=2
|
|
19
19
|
Requires-Dist: Flask-RESTful>=0.3.9
|
|
20
20
|
Requires-Dist: gunicorn>=20
|
|
@@ -33,9 +33,10 @@ Requires-Dist: jsonschema>=3
|
|
|
33
33
|
1. a flask-based wrapper to run a Python CLAMS app as an HTTP web app
|
|
34
34
|
1. cookie-cutter shell command that sets up everything and starts a new CLAMS app project
|
|
35
35
|
|
|
36
|
-
### Start now from [Getting Started](introduction.html)!
|
|
36
|
+
### Start now from [Getting Started](https://clamsproject.github.io/clams-python/introduction.html)!
|
|
37
37
|
|
|
38
38
|
## For more ...
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
* [Version history and patch notes](https://github.com/clamsproject/clams-python/blob/main/CHANGELOG.md)
|
|
40
|
+
* [CLAMS Python API documentation](https://clamsproject.github.io/clams-python/modules.html)
|
|
41
|
+
* [MMIF-specific Python API documentation](https://clamsproject.github.io/mmif-python)
|
|
42
|
+
* [Public CLAMS App Directory](https://clamsproject.github.io/apps)
|
|
@@ -127,7 +127,7 @@ class TestClamsApp(unittest.TestCase):
|
|
|
127
127
|
self.app.metadata.add_output(AnnotationTypes.BoundingBox, boxType='text')
|
|
128
128
|
metadata = json.loads(self.app.appmetadata())
|
|
129
129
|
self.assertEqual(len(metadata['output']), 2)
|
|
130
|
-
# these should not be added
|
|
130
|
+
# these should not be added because they are duplicates
|
|
131
131
|
with self.assertRaises(ValueError):
|
|
132
132
|
self.app.metadata.add_input(at_type=DocumentTypes.TextDocument)
|
|
133
133
|
with self.assertRaises(ValueError):
|
|
@@ -240,14 +240,19 @@ class TestClamsApp(unittest.TestCase):
|
|
|
240
240
|
with self.app.open_document_location(mmif.documents['i1'], Image.open) as f:
|
|
241
241
|
self.assertEqual(f.size, (200, 71))
|
|
242
242
|
|
|
243
|
-
def
|
|
243
|
+
def test_refine_parameters(self):
|
|
244
244
|
self.app.metadata.parameters = []
|
|
245
245
|
self.app.metadata.add_parameter('param1', 'first_param', 'string')
|
|
246
246
|
self.app.metadata.add_parameter('param2', 'second_param', 'string', default='second_default')
|
|
247
247
|
self.app.metadata.add_parameter('param3', 'third_param', 'boolean', default='f')
|
|
248
248
|
self.app.metadata.add_parameter('param4', 'fourth_param', 'integer', default='1', choices="1 2 3".split())
|
|
249
249
|
self.app.metadata.add_parameter('param5', 'fifth_param', 'number', default='0.5')
|
|
250
|
-
|
|
250
|
+
dummy_params = {'param1': 'okay', 'non_parameter': 'should be ignored'}
|
|
251
|
+
conf = self.app._refine_params(**dummy_params)
|
|
252
|
+
# should not refine what's already refined
|
|
253
|
+
double_refine = self.app._refine_params(**conf)
|
|
254
|
+
self.assertTrue(clams.ClamsApp._RAW_PARAMS_KEY in double_refine)
|
|
255
|
+
self.assertEqual(double_refine, conf)
|
|
251
256
|
conf.pop(clams.ClamsApp._RAW_PARAMS_KEY, None)
|
|
252
257
|
self.assertEqual(len(conf), 5) # 1 from `param1`, 4 from default value
|
|
253
258
|
self.assertFalse('non_parameter' in conf)
|
|
@@ -258,10 +263,10 @@ class TestClamsApp(unittest.TestCase):
|
|
|
258
263
|
self.assertEqual(type(conf['param5']), float)
|
|
259
264
|
with self.assertRaises(ValueError):
|
|
260
265
|
# because param1 doesn't have a default value and thus a required param
|
|
261
|
-
self.app.
|
|
266
|
+
self.app._refine_params(param2='okay')
|
|
262
267
|
with self.assertRaisesRegexp(ValueError, r'.+must be one of.+'):
|
|
263
268
|
# because param4 can't be 4, note that param1 is "required"
|
|
264
|
-
self.app.
|
|
269
|
+
self.app._refine_params(param1='p1', param4=4)
|
|
265
270
|
|
|
266
271
|
def test_error_handling(self):
|
|
267
272
|
params = {'raise_error': True, 'pretty': True}
|
|
@@ -383,7 +388,9 @@ class TestParameterCaster(unittest.TestCase):
|
|
|
383
388
|
'number_param': ["1.11"],
|
|
384
389
|
'int_param': [str(sys.maxsize)],
|
|
385
390
|
'bool_param': ['true'],
|
|
386
|
-
'str_multi_param': ['value1', 'value2']
|
|
391
|
+
'str_multi_param': ['value1', 'value2'],
|
|
392
|
+
'undefined_param_single': ['undefined_value1'],
|
|
393
|
+
'undefined_param_multi': ['undefined_value1', 'undefined_value2'],
|
|
387
394
|
}
|
|
388
395
|
self.assertTrue(all(map(lambda x: isinstance(x, str), itertools.chain.from_iterable(params.values()))))
|
|
389
396
|
casted = caster.cast(params)
|
|
@@ -393,6 +400,10 @@ class TestParameterCaster(unittest.TestCase):
|
|
|
393
400
|
self.assertTrue(isinstance(casted['int_param'], int))
|
|
394
401
|
self.assertTrue(casted['bool_param'])
|
|
395
402
|
self.assertEqual(set(casted['str_multi_param']), set(params['str_multi_param']))
|
|
403
|
+
self.assertTrue('undefined_param_single' in casted)
|
|
404
|
+
self.assertTrue('undefined_param_multi' in casted)
|
|
405
|
+
self.assertFalse(isinstance(casted['undefined_param_single'], list))
|
|
406
|
+
self.assertTrue(isinstance(casted['undefined_param_multi'], list))
|
|
396
407
|
unknown_param_key = 'unknown'
|
|
397
408
|
unknown_param_val = 'dunno'
|
|
398
409
|
params[unknown_param_key] = [unknown_param_val]
|
clams-python-1.1.0/VERSION
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
1.1.0
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "1.1.0"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{clams-python-1.1.0 → clams-python-1.1.2}/clams/develop/templates/app/.dockerignore.template
RENAMED
|
File without changes
|
|
File without changes
|
{clams-python-1.1.0 → clams-python-1.1.2}/clams/develop/templates/app/Containerfile.template
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{clams-python-1.1.0 → clams-python-1.1.2}/clams/develop/templates/app/requirements.txt.template
RENAMED
|
File without changes
|
{clams-python-1.1.0 → clams-python-1.1.2}/clams/develop/templates/gha/for-clams-team.md.template
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{clams-python-1.1.0 → clams-python-1.1.2}/clams/develop/templates/gha/workflows/publish.yml.template
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|