ramifice 0.8.4__py3-none-any.whl → 0.8.6__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.
@@ -3,12 +3,11 @@
3
3
  import uuid
4
4
  from base64 import b64decode
5
5
  from datetime import date
6
- from os.path import basename
7
- from pathlib import Path
6
+ from os import makedirs
7
+ from os.path import basename, exists, getsize
8
+ from shutil import copyfile
8
9
 
9
- from aiofiles import open as async_open
10
- from aiofiles import os as async_os
11
- from aioshutil import copyfile
10
+ from anyio import Path, open_file, to_thread
12
11
 
13
12
  from ramifice.fields.general.field import Field
14
13
  from ramifice.fields.general.file_group import FileGroup
@@ -128,12 +127,12 @@ class FileField(Field, FileGroup, JsonMixin):
128
127
  # Create path to target directory.
129
128
  dir_target_path = f"{MEDIA_ROOT}/uploads/{self.target_dir}/{date_str}"
130
129
  # Create target directory if it does not exist.
131
- if not await async_os.path.exists(dir_target_path):
132
- await async_os.makedirs(dir_target_path)
130
+ if not await to_thread.run_sync(exists, dir_target_path):
131
+ await to_thread.run_sync(makedirs, dir_target_path)
133
132
  # Create path to target file.
134
133
  f_target_path = f"{dir_target_path}/{f_uuid_name}"
135
134
  # Save file in target directory.
136
- async with async_open(f_target_path, mode="wb") as open_f:
135
+ async with await open_file(f_target_path, mode="wb") as open_f:
137
136
  f_content = b64decode(base64_str)
138
137
  await open_f.write(f_content)
139
138
  # Add paths to target file.
@@ -144,7 +143,7 @@ class FileField(Field, FileGroup, JsonMixin):
144
143
  # Add file extension.
145
144
  file_info["extension"] = extension
146
145
  # Add file size (in bytes).
147
- file_info["size"] = await async_os.path.getsize(f_target_path)
146
+ file_info["size"] = await to_thread.run_sync(getsize, f_target_path)
148
147
  #
149
148
  # to value.
150
149
  self.value = file_info
@@ -173,12 +172,12 @@ class FileField(Field, FileGroup, JsonMixin):
173
172
  # Create path to target directory.
174
173
  dir_target_path = f"{MEDIA_ROOT}/uploads/{self.target_dir}/{date_str}"
175
174
  # Create target directory if it does not exist.
176
- if not await async_os.path.exists(dir_target_path):
177
- await async_os.makedirs(dir_target_path)
175
+ if not await to_thread.run_sync(exists, dir_target_path):
176
+ await to_thread.run_sync(makedirs, dir_target_path)
178
177
  # Create path to target file.
179
178
  f_target_path = f"{dir_target_path}/{f_uuid_name}"
180
179
  # Save file in target directory.
181
- await copyfile(src_path, f_target_path)
180
+ await to_thread.run_sync(copyfile, src_path, f_target_path)
182
181
  # Add paths to target file.
183
182
  file_info["path"] = f_target_path
184
183
  file_info["url"] = f"{MEDIA_URL}/uploads/{self.target_dir}/{date_str}/{f_uuid_name}"
@@ -187,7 +186,7 @@ class FileField(Field, FileGroup, JsonMixin):
187
186
  # Add file extension.
188
187
  file_info["extension"] = extension
189
188
  # Add file size (in bytes).
190
- file_info["size"] = await async_os.path.getsize(f_target_path)
189
+ file_info["size"] = await to_thread.run_sync(getsize, f_target_path)
191
190
  #
192
191
  # to value.
193
192
  self.value = file_info
@@ -3,12 +3,11 @@
3
3
  import uuid
4
4
  from base64 import b64decode
5
5
  from datetime import date
6
- from os.path import basename
7
- from pathlib import Path
6
+ from os import makedirs
7
+ from os.path import basename, exists, getsize
8
+ from shutil import copyfile
8
9
 
9
- from aiofiles import open as async_open
10
- from aiofiles import os as async_os
11
- from aioshutil import copyfile
10
+ from anyio import Path, open_file, to_thread
12
11
 
13
12
  from ramifice.fields.general.field import Field
14
13
  from ramifice.fields.general.file_group import FileGroup
@@ -165,10 +164,10 @@ class ImageField(Field, FileGroup, JsonMixin):
165
164
  # Create path to main image.
166
165
  main_img_path = f"{imgs_dir_path}/{new_original_name}"
167
166
  # Create target directory if it does not exist.
168
- if not await async_os.path.exists(imgs_dir_path):
169
- await async_os.makedirs(imgs_dir_path)
167
+ if not await to_thread.run_sync(exists, imgs_dir_path):
168
+ await to_thread.run_sync(makedirs, imgs_dir_path)
170
169
  # Save main image in target directory.
171
- async with async_open(main_img_path, mode="wb") as open_f:
170
+ async with await open_file(main_img_path, mode="wb") as open_f:
172
171
  f_content = b64decode(base64_str)
173
172
  await open_f.write(f_content)
174
173
  # Add paths for main image.
@@ -188,7 +187,7 @@ class ImageField(Field, FileGroup, JsonMixin):
188
187
  # Add url path to target directory with images.
189
188
  img_info["imgs_dir_url"] = imgs_dir_url
190
189
  # Add size of main image (in bytes).
191
- img_info["size"] = await async_os.path.getsize(main_img_path)
190
+ img_info["size"] = await to_thread.run_sync(getsize, main_img_path)
192
191
  #
193
192
  # to value.
194
193
  self.value = img_info
@@ -223,10 +222,10 @@ class ImageField(Field, FileGroup, JsonMixin):
223
222
  # Create path to main image.
224
223
  main_img_path = f"{imgs_dir_path}/{new_original_name}"
225
224
  # Create target directory if it does not exist.
226
- if not await async_os.path.exists(imgs_dir_path):
227
- await async_os.makedirs(imgs_dir_path)
225
+ if not await to_thread.run_sync(exists, imgs_dir_path):
226
+ await to_thread.run_sync(makedirs, imgs_dir_path)
228
227
  # Save main image in target directory.
229
- await copyfile(src_path, main_img_path)
228
+ await to_thread.run_sync(copyfile, src_path, main_img_path)
230
229
  # Add paths for main image.
231
230
  img_info["path"] = main_img_path
232
231
  img_info["url"] = f"{imgs_dir_url}/{new_original_name}"
@@ -244,7 +243,7 @@ class ImageField(Field, FileGroup, JsonMixin):
244
243
  # Add url path to target directory with images.
245
244
  img_info["imgs_dir_url"] = imgs_dir_url
246
245
  # Add size of main image (in bytes).
247
- img_info["size"] = await async_os.path.getsize(main_img_path)
246
+ img_info["size"] = await to_thread.run_sync(getsize, main_img_path)
248
247
  #
249
248
  # to value.
250
249
  self.value = img_info
@@ -1,7 +1,7 @@
1
1
  """Decorator for converting Python classes into Ramifice models."""
2
2
 
3
- import os
4
3
  import re
4
+ from os.path import exists
5
5
  from typing import Any
6
6
 
7
7
  from ramifice.commons import QCommonsMixin
@@ -43,7 +43,7 @@ def model(
43
43
  if fixture_name is not None:
44
44
  fixture_path = f"config/fixtures/{fixture_name}.yml"
45
45
 
46
- if not os.path.exists(fixture_path):
46
+ if not exists(fixture_path):
47
47
  msg = (
48
48
  f"Model: `{cls.__module__}.{cls.__name__}` > "
49
49
  + f"META param: `fixture_name` => "
@@ -1,9 +1,10 @@
1
1
  """Validation of Model data before saving to the database."""
2
2
 
3
+ from os import remove
4
+ from shutil import rmtree
3
5
  from typing import Any
4
6
 
5
- from aiofiles import os as async_os
6
- from aioshutil import rmtree
7
+ from anyio import to_thread
7
8
  from bson.objectid import ObjectId
8
9
  from pymongo.asynchronous.collection import AsyncCollection
9
10
 
@@ -133,7 +134,7 @@ class CheckMixin(
133
134
  file_data = result_map.get(field_name)
134
135
  if file_data is not None:
135
136
  if file_data["is_new_file"]:
136
- await async_os.remove(file_data["path"])
137
+ await to_thread.run_sync(remove, file_data["path"])
137
138
  field_data.value = None
138
139
  if curr_doc is not None:
139
140
  field_data.value = curr_doc[field_name]
@@ -141,7 +142,7 @@ class CheckMixin(
141
142
  img_data = result_map.get(field_name)
142
143
  if img_data is not None:
143
144
  if img_data["is_new_img"]:
144
- await rmtree(img_data["imgs_dir_path"]) # type: ignore[call-arg]
145
+ await to_thread.run_sync(rmtree, img_data["imgs_dir_path"])
145
146
  field_data.value = None
146
147
  if curr_doc is not None:
147
148
  field_data.value = curr_doc[field_name]
@@ -1,9 +1,10 @@
1
1
  """Delete document from database."""
2
2
 
3
+ from os import remove
4
+ from shutil import rmtree
3
5
  from typing import Any
4
6
 
5
- from aiofiles import os as async_os
6
- from aioshutil import rmtree
7
+ from anyio import to_thread
7
8
  from pymongo.asynchronous.collection import AsyncCollection
8
9
 
9
10
  from ramifice.utils import constants
@@ -77,12 +78,12 @@ class DeleteMixin:
77
78
  if group == "file":
78
79
  file_data = mongo_doc[field_name]
79
80
  if file_data is not None and len(file_data["path"]) > 0:
80
- await async_os.remove(file_data["path"])
81
+ await to_thread.run_sync(remove, file_data["path"])
81
82
  file_data = None
82
83
  elif group == "img":
83
84
  file_data = mongo_doc[field_name]
84
85
  if file_data is not None and len(file_data["imgs_dir_path"]) > 0:
85
- await rmtree(file_data["imgs_dir_path"]) # type: ignore[call-arg]
86
+ await to_thread.run_sync(rmtree, file_data["imgs_dir_path"])
86
87
  file_data = None
87
88
  field_data.value = None
88
89
  # Run hook.
@@ -3,7 +3,7 @@
3
3
  Supported fields: ImageField
4
4
  """
5
5
 
6
- import asyncio
6
+ from asyncio import to_thread
7
7
  from typing import Any
8
8
 
9
9
  from PIL import Image
@@ -80,7 +80,7 @@ class ImgGroupMixin:
80
80
  # Extension to the upper register and delete the point.
81
81
  ext_upper = value["ext_upper"]
82
82
  # Get image file.
83
- with await asyncio.to_thread(Image.open, path) as img:
83
+ with await to_thread(Image.open, path) as img:
84
84
  width, height = img.size
85
85
  value["width"] = width
86
86
  value["height"] = height
@@ -93,7 +93,7 @@ class ImgGroupMixin:
93
93
  if size_name == "lg":
94
94
  value["path_lg"] = f"{imgs_dir_path}/lg{extension}"
95
95
  value["url_lg"] = f"{imgs_dir_url}/lg{extension}"
96
- await asyncio.to_thread(
96
+ await to_thread(
97
97
  img.save,
98
98
  fp=value["path_lg"],
99
99
  format=ext_upper,
@@ -101,7 +101,7 @@ class ImgGroupMixin:
101
101
  elif size_name == "md":
102
102
  value["path_md"] = f"{imgs_dir_path}/md{extension}"
103
103
  value["url_md"] = f"{imgs_dir_url}/md{extension}"
104
- await asyncio.to_thread(
104
+ await to_thread(
105
105
  img.save,
106
106
  fp=value["path_md"],
107
107
  format=ext_upper,
@@ -109,7 +109,7 @@ class ImgGroupMixin:
109
109
  elif size_name == "sm":
110
110
  value["path_sm"] = f"{imgs_dir_path}/sm{extension}"
111
111
  value["url_sm"] = f"{imgs_dir_url}/sm{extension}"
112
- await asyncio.to_thread(
112
+ await to_thread(
113
113
  img.save,
114
114
  fp=value["path_sm"],
115
115
  format=ext_upper,
@@ -117,7 +117,7 @@ class ImgGroupMixin:
117
117
  elif size_name == "xs":
118
118
  value["path_xs"] = f"{imgs_dir_path}/xs{extension}"
119
119
  value["url_xs"] = f"{imgs_dir_url}/xs{extension}"
120
- await asyncio.to_thread(
120
+ await to_thread(
121
121
  img.save,
122
122
  fp=value["path_xs"],
123
123
  format=ext_upper,
ramifice/utils/tools.py CHANGED
@@ -1,13 +1,13 @@
1
1
  """Global collection of auxiliary methods."""
2
2
 
3
- import asyncio
4
3
  import ipaddress
5
4
  import math
5
+ from asyncio import to_thread
6
+ from os.path import getsize
6
7
  from typing import Any
7
8
  from urllib.parse import urlparse
8
9
 
9
10
  import phonenumbers
10
- from aiofiles import ospath
11
11
  from bson.objectid import ObjectId
12
12
  from email_validator import EmailNotValidError, validate_email
13
13
 
@@ -31,7 +31,7 @@ def to_human_size(size: int) -> str:
31
31
 
32
32
  async def get_file_size(path: str) -> int:
33
33
  """Get file size in bytes."""
34
- size: int = await ospath.getsize(path)
34
+ size: int = await to_thread(getsize, path)
35
35
  return size
36
36
 
37
37
 
@@ -43,7 +43,10 @@ def normal_email(email: str | None) -> str | None:
43
43
  """
44
44
  normal: str | None = None
45
45
  try:
46
- emailinfo = validate_email(str(email), check_deliverability=False)
46
+ emailinfo = validate_email(
47
+ str(email),
48
+ check_deliverability=False,
49
+ )
47
50
  normal = emailinfo.normalized
48
51
  except EmailNotValidError:
49
52
  pass
@@ -53,7 +56,7 @@ def normal_email(email: str | None) -> str | None:
53
56
  async def is_email(email: str | None) -> bool:
54
57
  """Validate Email address."""
55
58
  try:
56
- await asyncio.to_thread(
59
+ await to_thread(
57
60
  validate_email,
58
61
  str(email),
59
62
  check_deliverability=True,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ramifice
3
- Version: 0.8.4
3
+ Version: 0.8.6
4
4
  Summary: ORM-like API MongoDB for Python language.
5
5
  Project-URL: Homepage, https://github.com/kebasyaty/ramifice
6
6
  Project-URL: Documentation, https://kebasyaty.github.io/ramifice/
@@ -23,8 +23,7 @@ Classifier: Programming Language :: Python :: Implementation :: CPython
23
23
  Classifier: Topic :: Database
24
24
  Classifier: Typing :: Typed
25
25
  Requires-Python: <4.0,>=3.12
26
- Requires-Dist: aiofiles>=24.1.0
27
- Requires-Dist: aioshutil>=1.5
26
+ Requires-Dist: anyio>=4.9.0
28
27
  Requires-Dist: argon2-cffi>=25.1.0
29
28
  Requires-Dist: babel>=2.17.0
30
29
  Requires-Dist: email-validator>=2.2.0
@@ -598,35 +597,6 @@ path = "public/media/default/no_doc.odt"
598
597
  size: int = get_file_size(path) # => 9843
599
598
  ```
600
599
 
601
- ## Contributing
602
-
603
- 1. Fork it (<https://github.com/kebasyaty/ramifice/fork>)
604
- 2. Create your feature branch (`git checkout -b my-new-feature`)
605
- 3. Commit your changes (`git commit -am 'Add some feature'`)
606
- 4. Push to the branch (`git push origin my-new-feature`)
607
- 5. Create a new Pull Request
608
-
609
- ## Install for development of Ramifice
610
-
611
- ```shell
612
- # Fedora:
613
- sudo dnf install gettext
614
- gettext --version
615
- # Ubuntu:
616
- sudo apt install gettext
617
- gettext --version
618
- # Windows:
619
- https://mlocati.github.io/articles/gettext-iconv-windows.html
620
- gettext --version
621
-
622
- cd project_name
623
- uv sync
624
- ```
625
-
626
- ## Contributors
627
-
628
- - [kebasyaty](https://github.com/kebasyaty) Gennady Kostyunin - creator and maintainer
629
-
630
600
  ## Changelog
631
601
 
632
602
  [View the change history.](https://github.com/kebasyaty/ramifice/blob/v0/CHANGELOG.md "Changelog")
@@ -25,10 +25,10 @@ ramifice/fields/color_field.py,sha256=K-lYp8f08HTZt6WU0kY3CQWaAmx6I3-uyKHBq7xAeS
25
25
  ramifice/fields/date_field.py,sha256=-M_dD8tVUXcDCQD5Hy5Ns9Z2QGlRya0qbvoWgA4qpmg,5277
26
26
  ramifice/fields/date_time_field.py,sha256=ahjX-cD5Qj-V7JUi5QAZ8qgv9UePhYYYzJghiasKdqE,5312
27
27
  ramifice/fields/email_field.py,sha256=4Kxy1K6CXJUJ8Db0CQuopjodiY4ybe7V0GT756t7Nks,3481
28
- ramifice/fields/file_field.py,sha256=CSCHSExyXUsvLGGCj3WmBHM0YUUcK9QZZb3kB8r8HQs,8253
28
+ ramifice/fields/file_field.py,sha256=2uc2YyuS0WDYO-jD0I8b3RL74m1Fw5DKAc7GlkzU8LE,8305
29
29
  ramifice/fields/float_field.py,sha256=JeVwoIi6j-dovXarZ3NgmSQI7f3qZzydlRs_yqp3Faw,4637
30
30
  ramifice/fields/id_field.py,sha256=YO5oIwXtqgURjjd2oYe2ouXxdpaiJp5ZhUgUA2pkNeo,4183
31
- ramifice/fields/image_field.py,sha256=ZBbraEI0P5qWK1_xDnZ42YXhqgK4LdcL28vg9zgPBiw,11672
31
+ ramifice/fields/image_field.py,sha256=_UseQMYOh7jUebsH1u4bYlTt3xTM3Yb09yrTtQx2wi0,11724
32
32
  ramifice/fields/integer_field.py,sha256=xPwpdhYNz4MyHgOypqa29oGNdKZic05yyUYHg5CDD3E,4609
33
33
  ramifice/fields/ip_field.py,sha256=tBFGFMC_zwAyLGtVRNNfiu4vQoxXPcgVHhX_aoHrvns,3390
34
34
  ramifice/fields/password_field.py,sha256=USD4Y8MTI89QZVT6zqLGBmb5kqOKrXqh73-z99cOvtk,3266
@@ -44,11 +44,11 @@ ramifice/fields/general/file_group.py,sha256=pC9bGUpDeu7FLJVD6NMCzq18aPETotipknS
44
44
  ramifice/fields/general/number_group.py,sha256=LOPHbKAnIuqW4DEh2fH78w6qOQjp0OhkuP7MoikhlkA,761
45
45
  ramifice/fields/general/text_group.py,sha256=m9EnlYGwqlck-JIYOCUd0hUYAVr8jH4YCnTmm9QlCkQ,1103
46
46
  ramifice/models/__init__.py,sha256=h_QQ5rSJNZ-7kmx7wIFd8E8RmUS94b_x4jdwMbq8zm4,15
47
- ramifice/models/decorator.py,sha256=dzwC489KBjamQxrWNy8lrdXVLb3e8OKPWbPGJZqxaFA,5958
47
+ ramifice/models/decorator.py,sha256=4NwnWcu2wxiX0EI_YXhbleyn4LB22mgDaDkQzJbHKD0,5967
48
48
  ramifice/models/model.py,sha256=e5UWHKIHwm7saxQ4bbamsTkz1VVBIqTRlAmJCOg5uRE,7160
49
49
  ramifice/paladins/__init__.py,sha256=EJ6EEKXUcMG5P1bDmlEa4W3fsxSz5u6mzDG_oU1efMQ,618
50
- ramifice/paladins/check.py,sha256=c-7jbFV5qzE9nF8Cl6VSPA8DtziADOuV6j1rldnZBKI,6602
51
- ramifice/paladins/delete.py,sha256=teUyj-sosObatoaFpMC3wodC4GvWbzgJCCxsI_Z9vyk,3448
50
+ ramifice/paladins/check.py,sha256=sDTdUECMTSfV37Hm4_HDZOB_YRWs58H5fnOY6dTT90k,6619
51
+ ramifice/paladins/delete.py,sha256=V3vahfx_kVCv5dTG6PVRsDlehVk4OtET4nHtxr9M5s0,3465
52
52
  ramifice/paladins/password.py,sha256=G-tMz2dIiOYEhOeSHYgAmc2e4tG_TJ2gt5tzPwBapkw,3047
53
53
  ramifice/paladins/refrash.py,sha256=hIZQEBGtoIhuGGg2KQYGApCaMb8WhK_QZlzi1_-zzU0,1100
54
54
  ramifice/paladins/save.py,sha256=mFau65uWYy4dSVyTVdZGR3VUnP-I_NPdMvq7F5n1sFo,3899
@@ -60,7 +60,7 @@ ramifice/paladins/groups/choice_group.py,sha256=KmrjbuHLLl6yGbRkdoMflf1thh17GLWr
60
60
  ramifice/paladins/groups/date_group.py,sha256=V3MCp8eA7txVLh6xmg76G9_y62TzWIQWqH59Ip26Xag,3779
61
61
  ramifice/paladins/groups/file_group.py,sha256=ySS7L5zcm2XrZRQUUOU8kgzqrucZ95UYzXD6pALWqE4,2982
62
62
  ramifice/paladins/groups/id_group.py,sha256=zN_Glu_cMGk8jMSDli3vYPvYrQXvQJNJFzb-t-qtZlQ,1290
63
- ramifice/paladins/groups/img_group.py,sha256=YDJTvbRoqQ2nf7-2QbIQ72I4j_c98_d5LZNrD9kCy0Q,6040
63
+ ramifice/paladins/groups/img_group.py,sha256=YOTUiXlmpNcsbzuLOEGB0eyemQxwaLkOBN9kzPb-lkI,6015
64
64
  ramifice/paladins/groups/num_group.py,sha256=sbxzTdl33TVySfaNfqMixyBkJ69v6AqEgraFUN3Kftk,2317
65
65
  ramifice/paladins/groups/pass_group.py,sha256=uuIIqMBXsYG7vTHc_AhdgWuNCivxTgQMjkEu0-ElSmY,1887
66
66
  ramifice/paladins/groups/slug_group.py,sha256=ztiA2v7e5lQYRZtlLw8WGOhSWaYQfOdZ6wkKbx3ZbTM,2329
@@ -70,7 +70,7 @@ ramifice/utils/constants.py,sha256=dTSk07FVc6hgXwG1IF0_klPnbfxlFHiaRmym5zWgzIM,2
70
70
  ramifice/utils/errors.py,sha256=iuhq7fzpUmsOyeXeg2fJjta8yAuqlXLKsZVMpfUhtHE,1901
71
71
  ramifice/utils/fixtures.py,sha256=PMRl1Ud0Ek0eX5F7BPiL7az_H7YKtIVKB8MJ17CeBdw,3179
72
72
  ramifice/utils/migration.py,sha256=5VYYB7DFMzLCRYWdlwtqGRSUPFdXp5SMxuMWraofVCw,11106
73
- ramifice/utils/tools.py,sha256=DSSR__sHgfDlYF4vhtR8vmeFtgquonkM5W_3V3SX6Y0,2872
73
+ ramifice/utils/tools.py,sha256=6N0YNlYB6c6Tz-4rhHrZJPi-KCUbRZhtK0VXHdusnNs,2921
74
74
  ramifice/utils/translations.py,sha256=Ibx6HqPcnsNxuBfXDs9mCLEA7xu4mkl3q39vqFaK-GI,4233
75
75
  ramifice/utils/unit.py,sha256=PPNKWYFJ8cz0nwbBPaTdL58_Nr7N0fIHFJBpKG2ZLKI,2482
76
76
  ramifice/utils/mixins/__init__.py,sha256=GrxJDsw73bEkitIh0-0BCxNnUK-N5uRXMCRlaPoaz1o,265
@@ -78,7 +78,7 @@ ramifice/utils/mixins/add_valid.py,sha256=TLOObedzXNA9eCylfAVbVCqIKE5sV-P5AdIN7a
78
78
  ramifice/utils/mixins/hooks.py,sha256=33jvJRhfnJeL2Hd_YFXk3M_7wjqHaByU2wRjKyboL6s,914
79
79
  ramifice/utils/mixins/indexing.py,sha256=Z0427HoaVRyNmSNN8Fx0mSICgAKV-gDdu3iR5qYUEbs,329
80
80
  ramifice/utils/mixins/json_converter.py,sha256=2K_PZ34AzpesusgyyQFOLXFPcjXez3TWn-m9CHIKwRo,1131
81
- ramifice-0.8.4.dist-info/METADATA,sha256=D7LCsTfcUITuLa2XzN_DS5sSgED6Scv9JfaXcu5b84k,21016
82
- ramifice-0.8.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
83
- ramifice-0.8.4.dist-info/licenses/LICENSE,sha256=LrEL0aTZx90HDwFUQCJutORiDjJL9AnuVvCtspXIqt4,1095
84
- ramifice-0.8.4.dist-info/RECORD,,
81
+ ramifice-0.8.6.dist-info/METADATA,sha256=uKZLkbRVu90gLBXO-Rmt1YeZs8yBS1oH_slrwEV5K_U,20313
82
+ ramifice-0.8.6.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
83
+ ramifice-0.8.6.dist-info/licenses/LICENSE,sha256=LrEL0aTZx90HDwFUQCJutORiDjJL9AnuVvCtspXIqt4,1095
84
+ ramifice-0.8.6.dist-info/RECORD,,