eido 0.2.1__py3-none-any.whl → 0.2.3__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.
eido/_version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.2.1"
1
+ __version__ = "0.2.3"
eido/argparser.py CHANGED
@@ -88,16 +88,6 @@ def build_argparser():
88
88
  metavar="S",
89
89
  )
90
90
 
91
- sps[VALIDATE_CMD].add_argument(
92
- "-e",
93
- "--exclude-case",
94
- default=False,
95
- action="store_true",
96
- help="Whether to exclude the validation case from an error. "
97
- "Only the human readable message explaining the error will "
98
- "be raised. Useful when validating large PEPs.",
99
- )
100
-
101
91
  sps[INSPECT_CMD].add_argument(
102
92
  "-n",
103
93
  "--sample-name",
eido/cli.py CHANGED
@@ -142,19 +142,19 @@ def main():
142
142
  f"against a schema: {args.schema}"
143
143
  )
144
144
  validator = validate_sample
145
- arguments = [p, args.sample_name, args.schema, args.exclude_case]
145
+ arguments = [p, args.sample_name, args.schema]
146
146
  elif args.just_config:
147
147
  _LOGGER.debug(
148
148
  f"Comparing Project ('{args.pep}') against a schema: {args.schema}"
149
149
  )
150
150
  validator = validate_config
151
- arguments = [p, args.schema, args.exclude_case]
151
+ arguments = [p, args.schema]
152
152
  else:
153
153
  _LOGGER.debug(
154
154
  f"Comparing Project ('{args.pep}') against a schema: {args.schema}"
155
155
  )
156
156
  validator = validate_project
157
- arguments = [p, args.schema, args.exclude_case]
157
+ arguments = [p, args.schema]
158
158
  try:
159
159
  validator(*arguments)
160
160
  except EidoValidationError as e:
eido/const.py CHANGED
@@ -14,8 +14,11 @@ SUBPARSER_MSGS = {
14
14
  CONVERT_CMD: "Convert PEP format using filters",
15
15
  }
16
16
  PROP_KEY = "properties"
17
- REQUIRED_FILES_KEY = "required_files"
18
- FILES_KEY = "files"
17
+
18
+ SAMPLES_KEY = "samples"
19
+
20
+ TANGIBLE_KEY = "tangible"
21
+ SIZING_KEY = "sizing"
19
22
 
20
23
  # sample schema input validation key names, these values are required by looper
21
24
  # to refer to the dict values
@@ -34,7 +37,9 @@ GENERAL = [
34
37
  "FILTERS_CMD",
35
38
  "SUBPARSER_MSGS",
36
39
  ]
37
- SCHEMA_SECTIONS = ["PROP_KEY", "REQUIRED_FILES_KEY", "FILES_KEY"]
40
+
41
+ SCHEMA_SECTIONS = ["PROP_KEY", "TANGIBLE_KEY", "SIZING_KEY"]
42
+
38
43
  SCHEMA_VALIDAION_KEYS = [
39
44
  "MISSING_KEY",
40
45
  "REQUIRED_INPUTS_KEY",
eido/conversion.py CHANGED
@@ -1,12 +1,15 @@
1
- import inspect
2
1
  import sys
3
- import os
4
- from logging import getLogger
5
2
 
6
- from pkg_resources import iter_entry_points
3
+ if sys.version_info < (3, 10):
4
+ from importlib_metadata import entry_points
5
+ else:
6
+ from importlib.metadata import entry_points
7
+ import inspect
8
+ from logging import getLogger
9
+ import os
10
+ from typing import NoReturn
7
11
 
8
12
  from .exceptions import *
9
- from typing import NoReturn
10
13
 
11
14
  _LOGGER = getLogger(__name__)
12
15
 
@@ -21,7 +24,7 @@ def pep_conversion_plugins():
21
24
  :raise EidoFilterError: if any of the filters has an invalid signature.
22
25
  """
23
26
  plugins = {}
24
- for ep in iter_entry_points("pep.filters"):
27
+ for ep in entry_points(group="pep.filters"):
25
28
  plugin_fun = ep.load()
26
29
  if len(list(inspect.signature(plugin_fun).parameters)) != 2:
27
30
  raise EidoFilterError(
@@ -1,4 +1,5 @@
1
1
  """ built-in PEP filters """
2
+
2
3
  from typing import Dict
3
4
  from .output_formatters import MultilineOutputFormatter
4
5
 
@@ -73,10 +74,12 @@ def processed_pep_filter(p, **kwargs) -> Dict[str, str]:
73
74
 
74
75
  return {
75
76
  "project": str(prj_repr),
76
- "samples": str(p.samples)
77
- if samples_as_objects
78
- else str(p.sample_table.to_csv()),
79
- "subsamples": str(p.subsamples)
80
- if subsamples_as_objects
81
- else str(p.subsample_table.to_csv()),
77
+ "samples": (
78
+ str(p.samples) if samples_as_objects else str(p.sample_table.to_csv())
79
+ ),
80
+ "subsamples": (
81
+ str(p.subsamples)
82
+ if subsamples_as_objects
83
+ else str(p.subsample_table.to_csv())
84
+ ),
82
85
  }
eido/exceptions.py CHANGED
@@ -43,3 +43,7 @@ class EidoValidationError(EidoException):
43
43
  def __init__(self, message, errors_by_type):
44
44
  super().__init__(message)
45
45
  self.errors_by_type = errors_by_type
46
+ self.message = message
47
+
48
+ def __str__(self):
49
+ return f"EidoValidationError ({self.message}): {self.errors_by_type}"
eido/inspection.py CHANGED
@@ -7,12 +7,13 @@ from ubiquerg import size
7
7
 
8
8
  from .const import (
9
9
  ALL_INPUTS_KEY,
10
- FILES_KEY,
11
10
  INPUT_FILE_SIZE_KEY,
12
11
  MISSING_KEY,
13
12
  PROP_KEY,
14
- REQUIRED_FILES_KEY,
15
13
  REQUIRED_INPUTS_KEY,
14
+ SIZING_KEY,
15
+ TANGIBLE_KEY,
16
+ SAMPLES_KEY,
16
17
  )
17
18
  from .schema import read_schema
18
19
  from .validation import _validate_sample_object, _get_attr_values
@@ -67,17 +68,21 @@ def get_input_files_size(sample, schema):
67
68
  all_inputs = set()
68
69
  required_inputs = set()
69
70
  schema = schema[-1] # use only first schema, in case there are imports
70
- sample_schema_dict = schema["properties"]["_samples"]["items"]
71
- if FILES_KEY in sample_schema_dict:
72
- all_inputs.update(_get_attr_values(sample, sample_schema_dict[FILES_KEY]))
73
- if REQUIRED_FILES_KEY in sample_schema_dict:
71
+ sample_schema_dict = schema[PROP_KEY][SAMPLES_KEY]["items"]
72
+ if SIZING_KEY in sample_schema_dict:
73
+ all_inputs.update(_get_attr_values(sample, sample_schema_dict[SIZING_KEY]))
74
+ if TANGIBLE_KEY in sample_schema_dict:
74
75
  required_inputs = set(
75
- _get_attr_values(sample, sample_schema_dict[REQUIRED_FILES_KEY])
76
+ _get_attr_values(sample, sample_schema_dict[TANGIBLE_KEY])
76
77
  )
77
78
  all_inputs.update(required_inputs)
78
79
  with catch_warnings(record=True) as w:
79
80
  input_file_size = sum(
80
- [size(f, size_str=False) or 0.0 for f in all_inputs if f != ""]
81
+ [
82
+ size(f, size_str=False) or 0.0
83
+ for f in all_inputs
84
+ if f != "" and f != None
85
+ ]
81
86
  ) / (1024**3)
82
87
  if w:
83
88
  _LOGGER.warning(
eido/schema.py CHANGED
@@ -2,7 +2,7 @@ from logging import getLogger
2
2
 
3
3
  from peppy.utils import load_yaml
4
4
 
5
- from .const import *
5
+ from .const import SAMPLES_KEY, PROP_KEY
6
6
 
7
7
  _LOGGER = getLogger(__name__)
8
8
 
@@ -21,23 +21,15 @@ def preprocess_schema(schema_dict):
21
21
  :return dict: preprocessed schema
22
22
  """
23
23
  _LOGGER.debug(f"schema ori: {schema_dict}")
24
- if "config" in schema_dict[PROP_KEY]:
25
- schema_dict[PROP_KEY]["_config"] = schema_dict[PROP_KEY]["config"]
26
- del schema_dict[PROP_KEY]["config"]
27
- else:
28
- _LOGGER.debug("No config section found in schema")
29
- if "samples" in schema_dict[PROP_KEY]:
30
- schema_dict[PROP_KEY]["_samples"] = schema_dict[PROP_KEY]["samples"]
31
- del schema_dict[PROP_KEY]["samples"]
32
- if "required" in schema_dict:
33
- schema_dict["required"][
34
- schema_dict["required"].index("samples")
35
- ] = "_samples"
24
+ if "project" not in schema_dict[PROP_KEY]:
25
+ _LOGGER.debug("No project section found in schema")
26
+
27
+ if SAMPLES_KEY in schema_dict[PROP_KEY]:
36
28
  if (
37
- "items" in schema_dict[PROP_KEY]["_samples"]
38
- and PROP_KEY in schema_dict[PROP_KEY]["_samples"]["items"]
29
+ "items" in schema_dict[PROP_KEY][SAMPLES_KEY]
30
+ and PROP_KEY in schema_dict[PROP_KEY][SAMPLES_KEY]["items"]
39
31
  ):
40
- s_props = schema_dict[PROP_KEY]["_samples"]["items"][PROP_KEY]
32
+ s_props = schema_dict[PROP_KEY][SAMPLES_KEY]["items"][PROP_KEY]
41
33
  for prop, val in s_props.items():
42
34
  if "type" in val and val["type"] in ["string", "number", "boolean"]:
43
35
  s_props[prop] = {}
eido/validation.py CHANGED
@@ -1,4 +1,5 @@
1
1
  import os
2
+ from typing import NoReturn, Mapping, Union
2
3
  from copy import deepcopy as dpcpy
3
4
  from logging import getLogger
4
5
 
@@ -6,34 +7,31 @@ from warnings import warn
6
7
 
7
8
  from .exceptions import EidoValidationError
8
9
 
9
-
10
10
  from pandas.core.common import flatten
11
11
  from jsonschema import Draft7Validator
12
+ import peppy
12
13
 
13
- from .const import (
14
- FILES_KEY,
15
- PROP_KEY,
16
- REQUIRED_FILES_KEY,
17
- )
14
+ from .const import PROP_KEY, SIZING_KEY, TANGIBLE_KEY, SAMPLES_KEY
18
15
  from .exceptions import PathAttrNotFoundError
19
16
  from .schema import preprocess_schema, read_schema
20
17
 
21
18
  _LOGGER = getLogger(__name__)
22
19
 
23
20
 
24
- def _validate_object(object, schema, sample_name_colname=False):
21
+ def _validate_object(obj: Mapping, schema: Union[str, dict], sample_name_colname=False):
25
22
  """
26
23
  Generic function to validate object against a schema
27
24
 
28
- :param Mapping object: an object to validate
25
+ :param Mapping obj: an object to validate
29
26
  :param str | dict schema: schema dict to validate against or a path to one
30
27
  from the error. Useful when used ith large projects
28
+
31
29
  :raises EidoValidationError: if validation is unsuccessful
32
30
  """
33
31
  validator = Draft7Validator(schema)
34
- _LOGGER.debug(f"{object},\n {schema}")
35
- if not validator.is_valid(object):
36
- errors = sorted(validator.iter_errors(object), key=lambda e: e.path)
32
+ _LOGGER.debug(f"{obj},\n {schema}")
33
+ if not validator.is_valid(obj):
34
+ errors = sorted(validator.iter_errors(obj), key=lambda e: e.path)
37
35
  errors_by_type = {}
38
36
 
39
37
  # Accumulate and restructure error objects by error type
@@ -58,13 +56,16 @@ def _validate_object(object, schema, sample_name_colname=False):
58
56
  _LOGGER.debug("Validation was successful...")
59
57
 
60
58
 
61
- def validate_project(project, schema):
59
+ def validate_project(project: peppy.Project, schema: Union[str, dict]) -> NoReturn:
62
60
  """
63
61
  Validate a project object against a schema
64
62
 
65
63
  :param peppy.Project project: a project object to validate
66
64
  :param str | dict schema: schema dict to validate against or a path to one
67
65
  from the error. Useful when used ith large projects
66
+
67
+ :return: NoReturn
68
+ :raises EidoValidationError: if validation is unsuccessful
68
69
  """
69
70
  sample_name_colname = project.sample_name_colname
70
71
  schema_dicts = read_schema(schema=schema)
@@ -76,7 +77,7 @@ def validate_project(project, schema):
76
77
  _LOGGER.debug("Project validation successful")
77
78
 
78
79
 
79
- def _validate_sample_object(sample, schemas):
80
+ def _validate_sample_object(sample: peppy.Sample, schemas):
80
81
  """
81
82
  Internal function that allows to validate a peppy.Sample object without
82
83
  requiring a reference to peppy.Project.
@@ -86,20 +87,24 @@ def _validate_sample_object(sample, schemas):
86
87
  """
87
88
  for schema_dict in schemas:
88
89
  schema_dict = preprocess_schema(schema_dict)
89
- sample_schema_dict = schema_dict[PROP_KEY]["_samples"]["items"]
90
+ sample_schema_dict = schema_dict[PROP_KEY][SAMPLES_KEY]["items"]
90
91
  _validate_object(sample.to_dict(), sample_schema_dict)
91
92
  _LOGGER.debug(
92
93
  f"{getattr(sample, 'sample_name', '')} sample validation successful"
93
94
  )
94
95
 
95
96
 
96
- def validate_sample(project, sample_name, schema):
97
+ def validate_sample(
98
+ project: peppy.Project, sample_name: Union[str, int], schema: Union[str, dict]
99
+ ) -> NoReturn:
97
100
  """
98
101
  Validate the selected sample object against a schema
99
102
 
100
103
  :param peppy.Project project: a project object to validate
101
104
  :param str | int sample_name: name or index of the sample to validate
102
105
  :param str | dict schema: schema dict to validate against or a path to one
106
+
107
+ :raises EidoValidationError: if validation is unsuccessful
103
108
  """
104
109
  sample = (
105
110
  project.samples[sample_name]
@@ -112,7 +117,9 @@ def validate_sample(project, sample_name, schema):
112
117
  )
113
118
 
114
119
 
115
- def validate_config(project, schema):
120
+ def validate_config(
121
+ project: Union[peppy.Project, dict], schema: Union[str, dict]
122
+ ) -> NoReturn:
116
123
  """
117
124
  Validate the config part of the Project object against a schema
118
125
 
@@ -123,17 +130,21 @@ def validate_config(project, schema):
123
130
  for schema_dict in schema_dicts:
124
131
  schema_cpy = preprocess_schema(dpcpy(schema_dict))
125
132
  try:
126
- del schema_cpy[PROP_KEY]["_samples"]
133
+ del schema_cpy[PROP_KEY][SAMPLES_KEY]
127
134
  except KeyError:
128
135
  pass
129
136
  if "required" in schema_cpy:
130
137
  try:
131
- schema_cpy["required"].remove("_samples")
138
+ schema_cpy["required"].remove(SAMPLES_KEY)
132
139
  except ValueError:
133
140
  pass
134
- project_dict = project.to_dict()
135
- _validate_object(project_dict, schema_cpy)
136
- _LOGGER.debug("Config validation successful")
141
+ if isinstance(project, dict):
142
+ _validate_object({"project": project}, schema_cpy)
143
+
144
+ else:
145
+ project_dict = project.to_dict()
146
+ _validate_object(project_dict, schema_cpy)
147
+ _LOGGER.debug("Config validation successful")
137
148
 
138
149
 
139
150
  def _get_attr_values(obj, attrlist):
@@ -157,7 +168,11 @@ def _get_attr_values(obj, attrlist):
157
168
  return list(flatten([getattr(obj, attr, "") for attr in attrlist]))
158
169
 
159
170
 
160
- def validate_input_files(project, schemas, sample_name=None):
171
+ def validate_input_files(
172
+ project: peppy.Project,
173
+ schemas: Union[str, dict],
174
+ sample_name: Union[str, int] = None,
175
+ ):
161
176
  """
162
177
  Determine which of the required and optional files are missing.
163
178
 
@@ -197,12 +212,12 @@ def validate_input_files(project, schemas, sample_name=None):
197
212
  all_inputs = set()
198
213
  required_inputs = set()
199
214
  schema = schemas[-1] # use only first schema, in case there are imports
200
- sample_schema_dict = schema["properties"]["_samples"]["items"]
201
- if FILES_KEY in sample_schema_dict:
202
- all_inputs.update(_get_attr_values(sample, sample_schema_dict[FILES_KEY]))
203
- if REQUIRED_FILES_KEY in sample_schema_dict:
215
+ sample_schema_dict = schema[PROP_KEY][SAMPLES_KEY]["items"]
216
+ if SIZING_KEY in sample_schema_dict:
217
+ all_inputs.update(_get_attr_values(sample, sample_schema_dict[SIZING_KEY]))
218
+ if TANGIBLE_KEY in sample_schema_dict:
204
219
  required_inputs = set(
205
- _get_attr_values(sample, sample_schema_dict[REQUIRED_FILES_KEY])
220
+ _get_attr_values(sample, sample_schema_dict[TANGIBLE_KEY])
206
221
  )
207
222
  all_inputs.update(required_inputs)
208
223
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: eido
3
- Version: 0.2.1
3
+ Version: 0.2.3
4
4
  Summary: A project metadata validator
5
5
  Home-page: https://github.com/pepkit/eido/
6
6
  Author: Michal Stolarczyk, Nathan Sheffield
@@ -15,11 +15,12 @@ Classifier: Programming Language :: Python :: 3.11
15
15
  Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
16
16
  Description-Content-Type: text/markdown
17
17
  License-File: LICENSE.txt
18
- Requires-Dist: jsonschema (>=3.0.1)
19
- Requires-Dist: logmuse (>=0.2.5)
18
+ Requires-Dist: jsonschema>=3.0.1
19
+ Requires-Dist: logmuse>=0.2.5
20
20
  Requires-Dist: pandas
21
- Requires-Dist: peppy (>=0.35.5)
22
- Requires-Dist: ubiquerg (>=0.5.2)
21
+ Requires-Dist: peppy>=0.40.6
22
+ Requires-Dist: ubiquerg>=0.5.2
23
+ Requires-Dist: importlib-metadata; python_version < "3.10"
23
24
 
24
25
  # <img src="docs/img/eido.svg" alt="eido logo" height="70">
25
26
 
@@ -28,4 +29,4 @@ Requires-Dist: ubiquerg (>=0.5.2)
28
29
  [![PEP compatible](http://pepkit.github.io/img/PEP-compatible-green.svg)](http://pepkit.github.io)
29
30
  [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
30
31
 
31
- [PEP](http://pepkit.github.io) validation tool based on [jsonschema](https://github.com/Julian/jsonschema). See [documentation](http://eido.databio.org) for usage.
32
+ [PEP](https://pep.databio.org) validation tool based on [jsonschema](https://github.com/Julian/jsonschema). See [documentation](http://pep.databio.org/eido) for usage.
@@ -0,0 +1,19 @@
1
+ eido/__init__.py,sha256=D3CD9BefyY5Yckz-LswPca_VH_RIcZpr53_siXkbi14,612
2
+ eido/__main__.py,sha256=L1wnnEreqYv27ZaaCwwImCIHZK0Mz5IxS80ZsNcS1zg,189
3
+ eido/_version.py,sha256=PNiDER4qM19h9zdsdfgKt2_dT4WgYK7EguJ8RU2qA_g,22
4
+ eido/argparser.py,sha256=vx59eO8CClaQpXehcW052y4HW5mttGTqM96PoJJwWkE,4806
5
+ eido/cli.py,sha256=dXPaqF6uUYnGMlW2H9Mc628CfhCl3pEinxWYnQ94SVc,5814
6
+ eido/const.py,sha256=Tb-fDKvneyZX3qLgLYVWtGGs4Hw4tRogB3OXIlwtpdY,1109
7
+ eido/conversion.py,sha256=MKuJWvLB10opq_noTiOSviiiJgMLY7n8B2stfCjEELE,4002
8
+ eido/conversion_plugins.py,sha256=zqjJbUo1p3l50NddGcO2KccnK5fXvQPe-GFyABr5Pg4,2529
9
+ eido/exceptions.py,sha256=C9gc_XnxYXT8uH7xXoh1NN7KUFXbRvLp4VN7H1DqF9w,1213
10
+ eido/inspection.py,sha256=rfuXnAawGBWQFz_hbJA2VYP_sFvpYxztxOiXL6t610o,3223
11
+ eido/output_formatters.py,sha256=bKqaashXRh-Vp6WbQzq8lQXbNHtvOR9IdXkn31rCmL8,4481
12
+ eido/schema.py,sha256=I75jlUlUdswkne6Xq2XLD8zm-f8p7VITQIj7J_x7aH8,2664
13
+ eido/validation.py,sha256=vmujhaDmNp2SFLhjBrh1SVGhM_NDf3ARVt91ZHaqrUA,8527
14
+ eido-0.2.3.dist-info/LICENSE.txt,sha256=oB6ZGDa4kcznznJKJsLLFFcOZyi8Y6e2Jv0rJozgp-I,1269
15
+ eido-0.2.3.dist-info/METADATA,sha256=kku0Ni4ZW43It53F7_xXQVVyKl7r9HIiBdRecT3USFM,1519
16
+ eido-0.2.3.dist-info/WHEEL,sha256=cVxcB9AmuTcXqmwrtPhNK88dr7IR_b6qagTj0UvIEbY,91
17
+ eido-0.2.3.dist-info/entry_points.txt,sha256=pu2Iw-IUjVa_bKRgt0xUtPT9iwfR0y2nfRYyaRlkLZU,263
18
+ eido-0.2.3.dist-info/top_level.txt,sha256=oltuMelApqcnJZ09Rrg3lF7kmTkmU5bcA6oRvXhNu6A,5
19
+ eido-0.2.3.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.40.0)
2
+ Generator: setuptools (74.1.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,19 +0,0 @@
1
- eido/__init__.py,sha256=D3CD9BefyY5Yckz-LswPca_VH_RIcZpr53_siXkbi14,612
2
- eido/__main__.py,sha256=L1wnnEreqYv27ZaaCwwImCIHZK0Mz5IxS80ZsNcS1zg,189
3
- eido/_version.py,sha256=HfjVOrpTnmZ-xVFCYSVmX50EXaBQeJteUHG-PD6iQs8,22
4
- eido/argparser.py,sha256=xsMMxmZ_9zU5JI_xAApUtO4oRtcpWgbfoQ1ABCt7FIE,5137
5
- eido/cli.py,sha256=H_YCYNpFzPhaIgv4u4t8eLq36dm7l3k95z2cPxTdGBg,5871
6
- eido/const.py,sha256=_t-T7erHpBJYDALTkQR8noItmgKe4hTGHt5ifzc6kO4,1096
7
- eido/conversion.py,sha256=gNGH7uBQcgR6Ngn_ZfnEysB9eBs1OQzAa5hd9v9LYl0,3912
8
- eido/conversion_plugins.py,sha256=Kcj3C6jHgM3NVwDcT2ZiyV2lwdMwuoNUe-pZ3DQLvSI,2488
9
- eido/exceptions.py,sha256=21RZCdScSo6uiHGWrh_yxi4ejGbtshK_IqYEqnZ10pk,1080
10
- eido/inspection.py,sha256=CiI1YEmUtPmXGaq_QohHWbtg_55LEcQB-TKxitlyjPY,3148
11
- eido/output_formatters.py,sha256=bKqaashXRh-Vp6WbQzq8lQXbNHtvOR9IdXkn31rCmL8,4481
12
- eido/schema.py,sha256=NXDUtwKtrWfCTGUqT72CNB1yAWPIfBSYQUNO2gszFvA,3042
13
- eido/validation.py,sha256=PIQut96FM3RLZtbWzFikQJXjUyQfgOCR68zD9O1Wt8E,7941
14
- eido-0.2.1.dist-info/LICENSE.txt,sha256=oB6ZGDa4kcznznJKJsLLFFcOZyi8Y6e2Jv0rJozgp-I,1269
15
- eido-0.2.1.dist-info/METADATA,sha256=ADJo6e_labpQmevfqk3MM0U2T9h0Fpp6BFtYJxxl8kk,1468
16
- eido-0.2.1.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
17
- eido-0.2.1.dist-info/entry_points.txt,sha256=pu2Iw-IUjVa_bKRgt0xUtPT9iwfR0y2nfRYyaRlkLZU,263
18
- eido-0.2.1.dist-info/top_level.txt,sha256=oltuMelApqcnJZ09Rrg3lF7kmTkmU5bcA6oRvXhNu6A,5
19
- eido-0.2.1.dist-info/RECORD,,