Get info on a data collection device for clinicedc/edc
Project description
|pypi| |travis| |coverage|
edc-device
----------
``edc-device`` provides device roles unique device IDs for hosts and clients where the hostname may not be reliable. Hosts can be group as servers, clients, node_servers and some of their functionality limited according to this role.
A unique device ID is used to seed unique subject and sample identifiers. Uniqueness is evaluated during deployment.
Device information is set in and read from ``edc_device.apps.AppConfig``.
You should subclass into your projects ``apps.py`` like this, for example:
.. code-block:: python
from edc_device.apps import AppConfig as EdcDeviceAppConfigParent
class EdcDeviceAppConfig(EdcDeviceAppConfigParent):
device_id = '32'
device_role = CLIENT
device_permissions = DevicePermissions(
plot_add, plot_change, ...)
and then in your settings:
.. code-block:: python
INSTALLED_APPS = [
...
my_app.apps.EdcDeviceAppConfig,
myapp.apps.AppConfig',
]
Include in your ``urls.py``:
.. code-block:: python
urlpatterns = [
...
path('edc_device/', include('edc_device.urls')),
...
]
To get to the Edc Device home page, reverse the url like this:
.. code-block:: python
reverse('edc_device:home_url')
Usage
=====
A ``client`` might look like this:
.. code-block:: python
class EdcDeviceAppConfig(EdcDeviceAppConfigParent):
device_id = '18'
node_server_id_list = [97, 98, 99]
middleman_id_list = [95, 96]
>>> from django.apps import apps as django_apps
>>> app_config = django_apps.get_app_config('edc_device')
>>> app_config.device_id
'18'
>>> app_config.is_client
True
>>> app_config.device_role
'Client'
A node server server might look like this:
.. code-block:: python
class EdcDeviceAppConfig(EdcDeviceAppConfigParent):
device_id = '98'
node_server_id_list = [97, 98, 99]
middleman_id_list = [95, 96]
>>> from django.apps import apps as django_apps
>>> app_config = django_apps.get_app_config('edc_device')
>>> app_config.device_id
'98'
>>> app_config.is_node_server
True
>>> app_config.device_role
'NodeServer'
A middleman server might look like this:
.. code-block:: python
class EdcDeviceAppConfig(EdcDeviceAppConfigParent):
device_id = '95'
node_server_id_list = [97, 98, 99]
middleman_id_list = [95, 96]
>>> from django.apps import apps as django_apps
>>> app_config = django_apps.get_app_config('edc_device')
>>> app_config.device_id
'95'
>>> app_config.is_middleman
True
>>> app_config.device_role
'Middleman'
The central server might look like this:
.. code-block:: python
class EdcDeviceAppConfig(EdcDeviceAppConfigParent):
device_id = '99'
node_server_id_list = [97, 98, 99]
middleman_id_list = [95, 96]
>>> from django.apps import apps as django_apps
>>> app_config = django_apps.get_app_config('edc_device')
>>> app_config.device_id
'99'
>>> app_config.is_middleman
True
>>> app_config.device_role
'CentralServer'
See also ``edc_sync``.
Device Permissions by Model
===========================
You can use the device role, or the device ID, to limit ADD/CHANGE permissions on a model.
``edc-device`` AppConfig maintains a collection of ``DeviceAddPermission`` and ``DeviceChangePermission`` instances that are inspected in the ``save`` method of a model using the ``DeviceModelMixin``.
To declare a ``DeviceAddPermission`` object:
.. code-block:: python
test_model_add = DeviceAddPermission(
model='my_app.mymodel, device_roles=[NODE_SERVER, CENTRAL_SERVER])
To declare a ``DeviceChangePermission`` object:
.. code-block:: python
test_model_change = DeviceChangePermission(
model='my_app.mymodel, device_roles=[CLIENT])
This means that if ``app_config.device_role`` is anything other than ``NODE_SERVER`` or ``CENTRAL_SERVER``, the save method will raise a ``DevicePermissionsAddError``.
To register the instances with ``edc_device.apps.AppConfig.device_permissions``:
.. code-block:: python
device_permissions = DevicePermissions(test_model_add, test_model_change)
This means that if ``app_config.device_role`` is anything other than ``CLIENT``, the save method will raise a ``DevicePermissionsChangeError``.
On boot up you should see:
.. code-block:: python
Loading Edc Device ...
* device id is '10'.
* device role is 'Client'.
* device permissions exist for:
- edc_device.testmodel ADD NodeServer,CentralServer
- edc_device.testmodel CHANGE Client
Done loading Edc Device.
Models declared with the ``EdcDeviceModelMixin`` check the device permissions collection on save. Note the model mixin is already declared with ``BaseUuidModel``.
.. code-block:: python
from edc_base.model_mixins import BaseUuidModel
class TestModel(BaseUuidModel):
pass
Declaring device permissions directly on model ``Meta`` class:
============================================================
You can declare device permissions on ``Meta.device_permissions`` in the same way as above.
.. code-block:: python
[...]
class Meta(DeviceModelMixin.Meta):
device_permissions = DevicePermissions(...)
Both ``Meta`` and ``AppConfig`` device permissions will be called, where the ``Meta`` class object will be called first.
Disable device permissions by model instance:
=============================================
You can disable device permissions _per model instance_ by setting ``check_device_permissions`` to ``False``
Customizing Device Permissions
==============================
The ADD and CHANGE device permission objects by default inspect the model's ``id``. If ``obj.id`` is ``None``, it as an ADD model operation; If ``obj.id`` is not ``None``, it is a CHANGE model operation.
You can change this by overriding the ``model_operation`` method. The ``model_operation`` must return ``None`` or some value, such as ``self.label``.
For example:
.. code-block:: python
# default for DeviceAddPermission
label = 'ADD'
def model_operation(self, model_obj=None, **kwargs):
if not model_obj.id:
return self.label
return None
# overridden
def model_operation(self, model_obj=None, **kwargs):
"""Return ADD if both id and plot identifier are None.
"""
if not model_obj.id and not obj.plot_identifier:
return self.label
return None
.. |pypi| image:: https://img.shields.io/pypi/v/edc-device.svg
:target: https://pypi.python.org/pypi/edc-device
.. |travis| image:: https://travis-ci.org/clinicedc/edc-device.svg?branch=develop
:target: https://travis-ci.org/clinicedc/edc-device
.. |coverage| image:: https://coveralls.io/repos/github/clinicedc/edc-device/badge.svg?branch=develop
:target: https://coveralls.io/github/clinicedc/edc-device?branch=develop
edc-device
----------
``edc-device`` provides device roles unique device IDs for hosts and clients where the hostname may not be reliable. Hosts can be group as servers, clients, node_servers and some of their functionality limited according to this role.
A unique device ID is used to seed unique subject and sample identifiers. Uniqueness is evaluated during deployment.
Device information is set in and read from ``edc_device.apps.AppConfig``.
You should subclass into your projects ``apps.py`` like this, for example:
.. code-block:: python
from edc_device.apps import AppConfig as EdcDeviceAppConfigParent
class EdcDeviceAppConfig(EdcDeviceAppConfigParent):
device_id = '32'
device_role = CLIENT
device_permissions = DevicePermissions(
plot_add, plot_change, ...)
and then in your settings:
.. code-block:: python
INSTALLED_APPS = [
...
my_app.apps.EdcDeviceAppConfig,
myapp.apps.AppConfig',
]
Include in your ``urls.py``:
.. code-block:: python
urlpatterns = [
...
path('edc_device/', include('edc_device.urls')),
...
]
To get to the Edc Device home page, reverse the url like this:
.. code-block:: python
reverse('edc_device:home_url')
Usage
=====
A ``client`` might look like this:
.. code-block:: python
class EdcDeviceAppConfig(EdcDeviceAppConfigParent):
device_id = '18'
node_server_id_list = [97, 98, 99]
middleman_id_list = [95, 96]
>>> from django.apps import apps as django_apps
>>> app_config = django_apps.get_app_config('edc_device')
>>> app_config.device_id
'18'
>>> app_config.is_client
True
>>> app_config.device_role
'Client'
A node server server might look like this:
.. code-block:: python
class EdcDeviceAppConfig(EdcDeviceAppConfigParent):
device_id = '98'
node_server_id_list = [97, 98, 99]
middleman_id_list = [95, 96]
>>> from django.apps import apps as django_apps
>>> app_config = django_apps.get_app_config('edc_device')
>>> app_config.device_id
'98'
>>> app_config.is_node_server
True
>>> app_config.device_role
'NodeServer'
A middleman server might look like this:
.. code-block:: python
class EdcDeviceAppConfig(EdcDeviceAppConfigParent):
device_id = '95'
node_server_id_list = [97, 98, 99]
middleman_id_list = [95, 96]
>>> from django.apps import apps as django_apps
>>> app_config = django_apps.get_app_config('edc_device')
>>> app_config.device_id
'95'
>>> app_config.is_middleman
True
>>> app_config.device_role
'Middleman'
The central server might look like this:
.. code-block:: python
class EdcDeviceAppConfig(EdcDeviceAppConfigParent):
device_id = '99'
node_server_id_list = [97, 98, 99]
middleman_id_list = [95, 96]
>>> from django.apps import apps as django_apps
>>> app_config = django_apps.get_app_config('edc_device')
>>> app_config.device_id
'99'
>>> app_config.is_middleman
True
>>> app_config.device_role
'CentralServer'
See also ``edc_sync``.
Device Permissions by Model
===========================
You can use the device role, or the device ID, to limit ADD/CHANGE permissions on a model.
``edc-device`` AppConfig maintains a collection of ``DeviceAddPermission`` and ``DeviceChangePermission`` instances that are inspected in the ``save`` method of a model using the ``DeviceModelMixin``.
To declare a ``DeviceAddPermission`` object:
.. code-block:: python
test_model_add = DeviceAddPermission(
model='my_app.mymodel, device_roles=[NODE_SERVER, CENTRAL_SERVER])
To declare a ``DeviceChangePermission`` object:
.. code-block:: python
test_model_change = DeviceChangePermission(
model='my_app.mymodel, device_roles=[CLIENT])
This means that if ``app_config.device_role`` is anything other than ``NODE_SERVER`` or ``CENTRAL_SERVER``, the save method will raise a ``DevicePermissionsAddError``.
To register the instances with ``edc_device.apps.AppConfig.device_permissions``:
.. code-block:: python
device_permissions = DevicePermissions(test_model_add, test_model_change)
This means that if ``app_config.device_role`` is anything other than ``CLIENT``, the save method will raise a ``DevicePermissionsChangeError``.
On boot up you should see:
.. code-block:: python
Loading Edc Device ...
* device id is '10'.
* device role is 'Client'.
* device permissions exist for:
- edc_device.testmodel ADD NodeServer,CentralServer
- edc_device.testmodel CHANGE Client
Done loading Edc Device.
Models declared with the ``EdcDeviceModelMixin`` check the device permissions collection on save. Note the model mixin is already declared with ``BaseUuidModel``.
.. code-block:: python
from edc_base.model_mixins import BaseUuidModel
class TestModel(BaseUuidModel):
pass
Declaring device permissions directly on model ``Meta`` class:
============================================================
You can declare device permissions on ``Meta.device_permissions`` in the same way as above.
.. code-block:: python
[...]
class Meta(DeviceModelMixin.Meta):
device_permissions = DevicePermissions(...)
Both ``Meta`` and ``AppConfig`` device permissions will be called, where the ``Meta`` class object will be called first.
Disable device permissions by model instance:
=============================================
You can disable device permissions _per model instance_ by setting ``check_device_permissions`` to ``False``
Customizing Device Permissions
==============================
The ADD and CHANGE device permission objects by default inspect the model's ``id``. If ``obj.id`` is ``None``, it as an ADD model operation; If ``obj.id`` is not ``None``, it is a CHANGE model operation.
You can change this by overriding the ``model_operation`` method. The ``model_operation`` must return ``None`` or some value, such as ``self.label``.
For example:
.. code-block:: python
# default for DeviceAddPermission
label = 'ADD'
def model_operation(self, model_obj=None, **kwargs):
if not model_obj.id:
return self.label
return None
# overridden
def model_operation(self, model_obj=None, **kwargs):
"""Return ADD if both id and plot identifier are None.
"""
if not model_obj.id and not obj.plot_identifier:
return self.label
return None
.. |pypi| image:: https://img.shields.io/pypi/v/edc-device.svg
:target: https://pypi.python.org/pypi/edc-device
.. |travis| image:: https://travis-ci.org/clinicedc/edc-device.svg?branch=develop
:target: https://travis-ci.org/clinicedc/edc-device
.. |coverage| image:: https://coveralls.io/repos/github/clinicedc/edc-device/badge.svg?branch=develop
:target: https://coveralls.io/github/clinicedc/edc-device?branch=develop
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Close
Hashes for edc-device-0.2.10.macosx-10.13-x86_64.tar.gz
Algorithm | Hash digest | |
---|---|---|
SHA256 | 327545a1634f75d241ab2c6068f9ba6a9969509b47f15a613265a7a5d4b2e104 |
|
MD5 | 7e5790af5da1b4391c9f9eb72c94830d |
|
BLAKE2b-256 | e6edd2cfde2a1cb2a1ecbaaf065193395ca03a657d25c009006ad1f021e76219 |
Close
Hashes for edc_device-0.2.10-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 61609f7ed60a087fb1a629f0b5adf401325720129ba0118e3792c7b3102adef6 |
|
MD5 | 33752a9c25c552de0ffd71da713698a1 |
|
BLAKE2b-256 | 0e74966a9709eee4e85eec1529df92f3399707d083ace104d1c6ca08876f058f |