clinicedc 2.0.23__py3-none-any.whl → 2.0.24__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 clinicedc might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: clinicedc
3
- Version: 2.0.23
3
+ Version: 2.0.24
4
4
  Summary: A clinical trials data management framework built on Django
5
5
  Keywords: django,clinicedc,edc,clinical trials,research,data management,esource
6
6
  Author: Erik van Widenfelt, Jonathan Willitts
@@ -2793,11 +2793,11 @@ edc_randomization/model_mixins.py,sha256=pKLkZJeYgobKPyHVJTby8Q7zBKQoflbLgraTN4p
2793
2793
  edc_randomization/models/__init__.py,sha256=iaJ6FM7VVqLpp8M-OjVWjohp4ELdxtPXqbEiT3iN5Tw,94
2794
2794
  edc_randomization/models/edc_permissions.py,sha256=f6P4zXxLQdTAbn2KnFlwfE86Lmzj7Ecp4JJ2F8mrwTc,286
2795
2795
  edc_randomization/models/randomization_list.py,sha256=Hd5yUSZ5HBKhNzYdlbJufab8U2x3Dzw8n4WXnYzJxyc,253
2796
- edc_randomization/randomization_list_importer.py,sha256=v8d1klIfAsf9CwR_4HLLzifDnJvFD2bXhDOe0XqznjM,12366
2797
- edc_randomization/randomization_list_verifier.py,sha256=0JqlbVCBZzx18Vxp2gID4zHjZMyO1LaHzqe4zTzRUpY,6481
2796
+ edc_randomization/randomization_list_importer.py,sha256=9jIJTG7rGjze4WmaFsJaw4qhFvy5mugZ4mx1CKKV6_o,12416
2797
+ edc_randomization/randomization_list_verifier.py,sha256=b9-ZbaWSSv6fCrrDgHjijUACTMsUuU_htbkHqAcE8l4,6669
2798
2798
  edc_randomization/randomizer.py,sha256=N57PvCGjsjlw4r4V-zE5K7uWnLUw4QwZREu-mQ-O_4U,12939
2799
2799
  edc_randomization/randomizers.py,sha256=JvMDAnsgvRZkl50Bawm2iLsyw3bfWfGwBafn54K5g44,297
2800
- edc_randomization/site_randomizers.py,sha256=T6u1cNPZtoh5ajdsBciSVWzZYZyOPbiTqS9VBGKJ7H8,4077
2800
+ edc_randomization/site_randomizers.py,sha256=et5Yf92ld8qgn-AThrBTRALB3WInI03UK4yGw2PlsKo,4499
2801
2801
  edc_randomization/system_checks.py,sha256=S_2Vkq3J3DQVEXOV3JNNlCzuZcl1l34-tTnaBaSZaBk,3025
2802
2802
  edc_randomization/urls.py,sha256=yQnOoy5U5uL00f7_JJcZk7toskmZunG_kJdl-epCV9U,223
2803
2803
  edc_randomization/utils.py,sha256=uRTtoyAuWo5D6y65ZHBWMSody8IMJBK6cS3mFmJGIMw,5730
@@ -3406,7 +3406,7 @@ edc_vitals/models/fields/waist_circumference.py,sha256=fZcHFDdEwWLjIVLktKrFCD9UU
3406
3406
  edc_vitals/models/fields/weight.py,sha256=zo9_9e3Cpu0UqoRbWS-iDkcDo6fK80b1dDQy4x4MyxE,921
3407
3407
  edc_vitals/utils.py,sha256=vXid44KUXxeaSyund_y5MNXc5DFJs052_PwUAjszE2k,1384
3408
3408
  edc_vitals/validators.py,sha256=vNiElWMs0rRnHRNuVoPLRf0rW_C_0xcfUyep1Y_Si5s,156
3409
- clinicedc-2.0.23.dist-info/licenses/LICENSE,sha256=jOtLnuWt7d5Hsx6XXB2QxzrSe2sWWh3NgMfFRetluQM,35147
3410
- clinicedc-2.0.23.dist-info/WHEEL,sha256=-neZj6nU9KAMg2CnCY6T3w8J53nx1kFGw_9HfoSzM60,79
3411
- clinicedc-2.0.23.dist-info/METADATA,sha256=E4Mthvgcki8gT3t1mDJIiAyqCER0KsawkYqC0hkWsSI,15787
3412
- clinicedc-2.0.23.dist-info/RECORD,,
3409
+ clinicedc-2.0.24.dist-info/licenses/LICENSE,sha256=jOtLnuWt7d5Hsx6XXB2QxzrSe2sWWh3NgMfFRetluQM,35147
3410
+ clinicedc-2.0.24.dist-info/WHEEL,sha256=-neZj6nU9KAMg2CnCY6T3w8J53nx1kFGw_9HfoSzM60,79
3411
+ clinicedc-2.0.24.dist-info/METADATA,sha256=SanRpzDjK5JhHNRsmoNLCYZtF9Q9k3bXXX2CdYsZ7ME,15787
3412
+ clinicedc-2.0.24.dist-info/RECORD,,
@@ -55,13 +55,13 @@ class RandomizationListImporter:
55
55
 
56
56
 
57
57
  Format:
58
- sid,assignment,site_name, orig_site, orig_allocation, orig_desc
59
- 1,single_dose,gaborone
60
- 2,two_doses,gaborone
58
+ sid,site_name, assignment, description, orig_site, orig_allocation, orig_desc
59
+ 1,gaborone,intervention,single_dose
60
+ 2,gaborone,control,two_doses
61
61
  ...
62
62
  """
63
63
 
64
- required_csv_fieldnames = ["sid", "assignment", "site_name"]
64
+ required_csv_fieldnames = ("sid", "assignment", "site_name", "description")
65
65
  verifier_cls = RandomizationListVerifier
66
66
 
67
67
  def __init__(
@@ -31,7 +31,7 @@ class RandomizationListVerifier:
31
31
  fieldnames=None,
32
32
  sid_count_for_tests=None,
33
33
  required_csv_fieldnames: list[str] | None = None,
34
- **kwargs,
34
+ **kwargs, # noqa: ARG002
35
35
  ):
36
36
  self.count: int = 0
37
37
  self.messages: list[str] = []
@@ -68,33 +68,38 @@ class RandomizationListVerifier:
68
68
  )
69
69
  elif message := self.verify():
70
70
  self.messages.append(message)
71
- if self.messages:
72
- if (
73
- "migrate" not in sys.argv
74
- and "makemigrations" not in sys.argv
75
- and "import_randomization_list" not in sys.argv
76
- ):
77
- raise RandomizationListError(", ".join(self.messages))
71
+ if self.messages and (
72
+ "migrate" not in sys.argv
73
+ and "makemigrations" not in sys.argv
74
+ and "import_randomization_list" not in sys.argv
75
+ ):
76
+ raise RandomizationListError(", ".join(self.messages))
78
77
 
79
78
  def verify(self) -> str | None:
80
79
  message = None
80
+
81
81
  with self.randomizationlist_path.open(mode="r") as f:
82
82
  reader = csv.DictReader(f)
83
- for index, row in enumerate(reader, start=1):
84
- row = {k: v.strip() for k, v in row.items() if k}
85
- message = self.inspect_row(index - 1, row)
86
- if message:
87
- break
88
- if self.sid_count_for_tests and index == self.sid_count_for_tests:
89
- break
90
- if not message:
91
- if self.count != index:
92
- message = (
93
- f"Randomization list count is off. Expected {index} (CSV). "
94
- f"Got {self.count} (model_cls). See file "
95
- f"{self.randomizationlist_path}. "
96
- f"Resolve this issue before using the system."
97
- )
83
+ all_rows = [{k: v.strip() for k, v in row.items() if k} for row in reader]
84
+ sorted_rows = sorted(
85
+ all_rows, key=lambda row: (row.get("site_name", ""), row.get("sid", ""))
86
+ )
87
+
88
+ for index, row in enumerate(sorted_rows, start=1):
89
+ sys.stdout.write(f"Index: {index}, SID: {row.get('sid')}, Row: {row}\n")
90
+ message = self.inspect_row(index - 1, row)
91
+ if message:
92
+ break
93
+ if self.sid_count_for_tests and index == self.sid_count_for_tests:
94
+ break
95
+
96
+ if not message and self.count != index:
97
+ message = (
98
+ f"Randomization list count is off. Expected {index} (CSV). "
99
+ f"Got {self.count} (model_cls). See file "
100
+ f"{self.randomizationlist_path}. "
101
+ f"Resolve this issue before using the system."
102
+ )
98
103
  return message
99
104
 
100
105
  def inspect_row(self, index: int, row) -> str | None:
@@ -103,7 +108,7 @@ class RandomizationListVerifier:
103
108
  Note:Index is zero-based
104
109
  """
105
110
  message = None
106
- obj1 = self.randomizer_model_cls.objects.all().order_by("sid")[index]
111
+ obj1 = self.randomizer_model_cls.objects.all().order_by("site_name", "sid")[index]
107
112
  try:
108
113
  obj2 = self.randomizer_model_cls.objects.get(sid=row["sid"])
109
114
  except ObjectDoesNotExist:
@@ -28,7 +28,22 @@ class SiteRandomizerError(Exception):
28
28
 
29
29
 
30
30
  class SiteRandomizers:
31
- """Main controller of :class:`SiteRandomizers` objects."""
31
+ """Main controller of :class:`SiteRandomizers` objects.
32
+
33
+ To rescan the CSV file for randomizer additional slots:
34
+
35
+ from edc_randomization.site_randomizers import site_randomizers
36
+ # assuming the randimizer is "default"
37
+ site_randomizers.get("default").import_list(add=True,dryrun=True)
38
+
39
+ If all OK:
40
+
41
+ # assuming the randimizer is "default"
42
+ site_randomizers.get("default").import_list(add=True,dryrun=False)
43
+
44
+ See
45
+
46
+ """
32
47
 
33
48
  def __init__(self):
34
49
  self._registry = {}
@@ -57,12 +72,12 @@ class SiteRandomizers:
57
72
  def get(self, name):
58
73
  try:
59
74
  return self._registry[str(name)]
60
- except KeyError:
75
+ except KeyError as e:
61
76
  raise NotRegistered(
62
77
  f"A Randomizer class by this name is not registered. "
63
78
  f"Expected one of {list(self._registry.keys())}. "
64
79
  f"Got '{name}'. See site_randomizer."
65
- )
80
+ ) from e
66
81
 
67
82
  def get_by_model(self, model=None):
68
83
  """Returns the randomizer class for this model label_lower.
@@ -75,10 +90,12 @@ class SiteRandomizers:
75
90
  return None
76
91
 
77
92
  def get_as_choices(self):
78
- choices = []
79
- for randomizer_cls in self._registry.values():
80
- choices.append((randomizer_cls.name, randomizer_cls.name))
81
- return tuple(choices)
93
+ return tuple(
94
+ [
95
+ (randomizer_cls.name, randomizer_cls.name)
96
+ for randomizer_cls in self._registry.values()
97
+ ]
98
+ )
82
99
 
83
100
  def randomize(
84
101
  self,
@@ -115,7 +132,7 @@ class SiteRandomizers:
115
132
  before_import_registry = copy.copy(site_randomizers._registry)
116
133
  import_module(f"{app}.{module_name}")
117
134
  if verbose:
118
- sys.stdout.write(" * registered randomizer from " f"'{app}'\n")
135
+ sys.stdout.write(f" * registered randomizer from '{app}'\n")
119
136
  except Exception as e:
120
137
  if f"No module named '{app}.{module_name}'" not in str(e):
121
138
  raise