Skip to content

Commit 89006f6

Browse files
authored
Merge pull request #145 from mdsol/feature/add_location_oid_type
Feature/add location oid type
2 parents cbdf33c + 542618e commit 89006f6

40 files changed

+521
-351
lines changed

.github/workflows/main.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ on:
1111
jobs:
1212
tests:
1313
name: "Python ${{ matrix.python-version }}"
14-
runs-on: "ubuntu-latest"
14+
runs-on: ubuntu-latest
1515
env:
16-
USING_COVERAGE: '3.7,3.8,3.10'
16+
USING_COVERAGE: '3.7,3.8,3.10,3.11,3.12'
1717

1818
strategy:
1919
matrix:
20-
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"]
20+
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"]
2121

2222
steps:
2323
- uses: actions/checkout@v3
@@ -60,7 +60,7 @@ jobs:
6060
# Install dependencies. `--no-root` means "install all dependencies but not the project
6161
# itself", which is what you want to avoid caching _your_ code. The `if` statement
6262
# ensures this only runs on a cache miss.
63-
- run: poetry install --no-interaction --no-root
63+
- run: poetry install --no-interaction --no-root --with dev
6464
if: steps.cache-deps.outputs.cache-hit != 'true'
6565

6666
# Now install _your_ project. This isn't necessary for many types of projects -- particularly

CONTRIBUTING.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@ Developer Setup
99
```
1010
git clone https://github.com/mdsol/rwslib
1111
```
12-
2. Create a Virtual Env for the Local instance
12+
2. Install poetry and start a shell
1313
```bash
14-
$ python -m venv venv
15-
$ source venv/bin/activate
14+
$ pip install poetry
15+
$ poetry shell
1616
```
1717
3. Install the development dependencies
1818
```bash
19-
$ pip install -r requirements-dev.txt
19+
$ poetry install --with dev
2020
```
2121
4. Enjoy !!!
2222

poetry.lock

Lines changed: 280 additions & 246 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "rwslib"
3-
version = "1.2.11"
3+
version = "1.2.12"
44
description = "Rave Web Services for Python"
55
authors = ["Ian Sparks <[email protected]>"]
66
maintainers = ["Geoff Low <[email protected]>"]
@@ -14,11 +14,9 @@ classifiers = [
1414
'Natural Language :: English',
1515
'License :: OSI Approved :: MIT License',
1616
'Programming Language :: Python',
17-
'Programming Language :: Python :: 3.7',
18-
'Programming Language :: Python :: 3.8',
19-
'Programming Language :: Python :: 3.9',
2017
'Programming Language :: Python :: 3.10',
2118
'Programming Language :: Python :: 3.11',
19+
'Programming Language :: Python :: 3.12',
2220
]
2321
packages = [
2422
{ include = "rwslib" },
@@ -33,19 +31,21 @@ click = "*"
3331
faker = "*"
3432
urllib3 = "*"
3533

34+
[tool.poetry.group.dev]
35+
optional = true
3636

3737
[tool.poetry.group.dev.dependencies]
3838
httpretty = "*"
3939
mock = "*"
4040
coverage = "*"
4141
pytest = "*"
4242
tox = "*"
43-
tox-poetry = "*"
4443

4544
[tool.poetry.group.docs.dependencies]
4645
Sphinx = "^5.1.1"
4746
sphinx-pyproject = "^0.3.0"
4847

4948
[build-system]
50-
requires = ["poetry-core"]
49+
requires = ["poetry-core>=1.0.0"]
5150
build-backend = "poetry.core.masonry.api"
51+

rwslib/builders/clinicaldata.py

Lines changed: 58 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
# -*- coding: utf-8 -*-
2+
from typing import Optional
3+
24
from rwslib.builders.common import (
35
ODMElement,
46
TransactionalElement,
@@ -8,7 +10,7 @@
810
)
911
from rwslib.builders.modm import LastUpdateMixin, MilestoneMixin
1012
from rwslib.builders.metadata import MeasurementUnitRef
11-
from rwslib.builders.constants import ProtocolDeviationStatus, QueryStatusType
13+
from rwslib.builders.constants import ProtocolDeviationStatus, QueryStatusType, LocationOIDType
1214
from rwslib.builders.common import Unset
1315

1416
from collections import OrderedDict
@@ -77,6 +79,7 @@ def __init__(
7779
subject_key,
7880
subject_key_type="SubjectName",
7981
transaction_type="Update",
82+
location_oid_type: Optional[LocationOIDType] = None,
8083
):
8184
"""
8285
:param str site_location_oid: :class:`SiteLocation` OID
@@ -98,6 +101,8 @@ def __init__(
98101
self.signature = None
99102
#: :class:`SiteRef`
100103
self.siteref = None
104+
#: :class:`LocationOIDType`
105+
self.location_oid_type = location_oid_type
101106

102107
def build(self, builder):
103108
"""Build XML by appending to builder"""
@@ -120,8 +125,8 @@ def build(self, builder):
120125
if self.siteref:
121126
self.siteref.build(builder)
122127
else:
123-
builder.start("SiteRef", {"LocationOID": self.sitelocationoid})
124-
builder.end("SiteRef")
128+
_siteref = SiteRef(self.sitelocationoid, self.location_oid_type)
129+
_siteref.build(builder)
125130

126131
for event in self.study_events:
127132
event.build(builder)
@@ -993,17 +998,66 @@ class SiteRef(ODMElement, LastUpdateMixin):
993998
.. note:: The `mdsol:LocationOIDType` attribute should be used to indicate the type of `LocationOID`
994999
"""
9951000

996-
def __init__(self, oid):
1001+
def __init__(self,
1002+
oid,
1003+
location_oid_type: Optional[LocationOIDType] = None,
1004+
site_number: Optional[str] = None,
1005+
study_site_name: Optional[str] = None,
1006+
site_uuid: Optional[str] = None,
1007+
location_name: Optional[str] = None,
1008+
study_env_site_number: Optional[str] = None,
1009+
previous_location_oid: Optional[str] = None,
1010+
shared_location_oid: Optional[str] = None,
1011+
previous_shared_location_oid: Optional[str] = None,
1012+
subject_created_at_site: Optional[str] = None,):
9971013
"""
9981014
:param str oid: OID for referenced :class:`Location`
1015+
:param LocationOIDType location_oid_type: Type for the oid
1016+
:param site_number: Site number
1017+
:param study_site_name: Study site name
1018+
:param site_uuid: Site UUID
1019+
:param location_name: Location name
1020+
:param study_env_site_number: Study environment site number
1021+
:param previous_location_oid: Previous location OID
1022+
:param shared_location_oid: Shared location OID
1023+
:param previous_shared_location_oid: Previous shared location OID
1024+
:param subject_created_at_site: Subject created at site
9991025
"""
10001026
self.oid = oid
1027+
self.location_oid_type = location_oid_type
1028+
self.site_number = site_number
1029+
self.study_site_name = study_site_name
1030+
self.site_uuid = site_uuid
1031+
self.location_name = location_name
1032+
self.study_env_site_number = study_env_site_number
1033+
self.previous_location_oid = previous_location_oid
1034+
self.shared_location_oid = shared_location_oid
1035+
self.previous_shared_location_oid = previous_shared_location_oid
1036+
self.subject_created_at_site = subject_created_at_site
10011037

10021038
def build(self, builder):
10031039
"""
10041040
Build XML by appending to builder
10051041
"""
10061042
params = dict(LocationOID=self.oid)
1043+
if self.location_oid_type:
1044+
params["mdsol:LocationOIDType"] = self.location_oid_type.value
1045+
elif self.site_uuid:
1046+
params["mdsol:SiteUUID"] = self.site_uuid
1047+
elif self.site_number:
1048+
params["mdsol:SiteNumber"] = self.site_number
1049+
elif self.study_site_name:
1050+
params["mdsol:StudySiteName"] = self.study_site_name
1051+
elif self.study_env_site_number:
1052+
params["mdsol:StudyEnvSiteNumber"] = self.study_env_site_number
1053+
if self.location_name:
1054+
params["mdsol:LocationName"] = self.location_name
1055+
if self.previous_location_oid:
1056+
params["mdsol:PreviousLocationOID"] = self.previous_location_oid
1057+
if self.shared_location_oid:
1058+
params["mdsol:SharedLocationOID"] = self.shared_location_oid
1059+
if self.subject_created_at_site:
1060+
params["mdsol:SubjectCreatedAtSite"] = self.subject_created_at_site
10071061
# mixins
10081062
self.mixin()
10091063
self.mixin_params(params)

rwslib/builders/common.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# -*- coding: utf-8 -*-
2-
2+
import platform
33
from string import ascii_letters
4-
from datetime import datetime
4+
import datetime
55
from xml.etree import cElementTree as ET
66

77

@@ -13,11 +13,21 @@
1313

1414
# -----------------------------------------------------------------------------------------------------------------------
1515
# Utilities
16+
def get_utc_date() -> datetime.datetime:
17+
"""
18+
Returns the UTC date as datetime.datetime object.
19+
"""
20+
version = platform.python_version_tuple()
21+
if int(version[1]) < 11:
22+
utc_date = datetime.datetime.utcnow()
23+
else:
24+
utc_date = datetime.datetime.now(datetime.UTC)
25+
return utc_date
1626

1727

1828
def now_to_iso8601():
1929
"""Returns NOW date/time as a UTC date/time formated as iso8601 string"""
20-
utc_date = datetime.utcnow()
30+
utc_date = get_utc_date()
2131
return dt_to_iso8601(utc_date)
2232

2333

rwslib/builders/constants.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,3 +329,14 @@ class GranularityType(enum.Enum):
329329
AllClinicalData = 'AllClinicalData'
330330
SingleSite = 'SingleSite'
331331
SingleSubject = 'SingleSubject'
332+
333+
334+
class LocationOIDType(enum.Enum):
335+
"""
336+
Location OID Type Enumeration
337+
Applies to a :class:`SiteRef`
338+
"""
339+
SiteUUID = 'SiteUUID'
340+
SiteNumber = 'SiteNumber'
341+
StudyEnvSiteNumber = 'StudyEnvSiteNumber'
342+

rwslib/builders/modm.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import datetime
66
import enum
77

8+
from rwslib.builders.common import get_utc_date
9+
810

911
class MODMExtensionRegistry(enum.Enum):
1012
"""
@@ -167,7 +169,7 @@ def set_update_time(self, update_time=None):
167169
if update_time and isinstance(update_time, (datetime.datetime,)):
168170
self.last_update_time = update_time
169171
else:
170-
self.last_update_time = datetime.datetime.utcnow()
172+
self.last_update_time = get_utc_date()
171173

172174
def mixin_params(self, params):
173175
"""

rwslib/tests/__init__.py

Lines changed: 0 additions & 12 deletions
This file was deleted.

tests/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)