Metadata-Version: 1.1
Name: edc-device
Version: 0.2.9
Summary: Get info on a data collection device for clinicedc/edc
Home-page: https://github.com/clinicedc/edc-device
Author: Erik van Widenfelt
Author-email: ew2789@gmail.com
License: GPL license, see LICENSE
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
        
        
Keywords: django contenttype
Platform: UNKNOWN
Classifier: Environment :: Web Environment
Classifier: Framework :: Django
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
