edc-sites


Nameedc-sites JSON
Version 0.3.66 PyPI version JSON
download
home_pagehttps://github.com/clinicedc/edc-sites
SummarySimple classes related to the django sites framework for clinicedc projects
upload_time2024-11-20 22:08:37
maintainerNone
docs_urlNone
authorErik van Widenfelt
requires_python>=3.12
licenseGPL license, see LICENSE
keywords django edc sites clinicedc clinical trials
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage
            |pypi| |actions| |codecov| |downloads|

edc-sites
---------

Site definitions to work with Django's `Sites Framework`__ and django_multisite_.

Define a ``sites.py``. This is usually in a separate project module. For example, for project ``meta`` there is a module ``meta_sites`` that contains a ``sites.py``.

Register your sites in ``sites.py``.

.. code-block:: python

    # sites.py
    from edc_sites.site import sites
    from edc_sites.single_site import SingleSite

	suffix = "example.clinicedc.org"

	sites.register(
	    SingleSite(
	        10,
	        "hindu_mandal",
	        title="Hindu Mandal Hospital",
	        country="tanzania",
	        country_code="tz",
	        domain=f"hindu_mandal.tz.{suffix}",
	    ),
	    SingleSite(
	        20,
	        "amana",
	        title="Amana Hospital",
	        country="tanzania",
	        country_code="tz",
	        domain=f"amana.tz.{suffix}",
	    ),
	)


A ``post_migrate`` signal is registered in ``apps.py`` to update the django model ``Site`` and the
EDC model ``SiteProfile`` on the next migration:

.. code-block:: python

	# apps.py

    from edc_sites.add_or_update_django_sites import add_or_update_django_sites

	def post_migrate_update_sites(sender=None, **kwargs):
	    sys.stdout.write(style.MIGRATE_HEADING("Updating sites:\n"))
	    add_or_update_django_sites(verbose=True)
	    sys.stdout.write("Done.\n")
	    sys.stdout.flush()



Now in your code you can use the ``sites`` global to inspect the trial sites:

.. code-block:: python

    from edc_sites.site import sites

    In [1]: sites.all()
    Out[1]:
    {10: SingleSite(site_id=10, name='hindu_mandal', domain='hindu_mandal.tz.example.clinicedc.org', country='tanzania', description='Hindu Mandal Hospital'),
     20: SingleSite(site_id=20, name='amana', domain='amana.tz.example.clinicedc.org', country='tanzania', description='Amana Hospital')}

    In [2]: sites.get(10)
    Out[2]: SingleSite(site_id=10, name='hindu_mandal', domain='hindu_mandal.tz.example.clinicedc.org', country='tanzania', description='Hindu Mandal Hospital')

    In [3]: sites.get_by_attr("name", 'hindu_mandal')
    Out[3]: SingleSite(site_id=10, name='hindu_mandal', domain='hindu_mandal.tz.example.clinicedc.org', country='tanzania', description='Hindu Mandal Hospital')

    In [4]: sites.get(10).languages
    Out[4]:
    {'sw': 'Swahili',
     'en-gb': 'British English',
     'en': 'English',
     'mas': 'Maasai',
     'ry': 'Runyakitara',
     'lg': 'Ganda',
     'rny': 'Runyankore'}


Take a look at the ``Sites`` class in edc_sites.site for more available methods.

For another deployment, we have alot of sites spread out over a few countries.

For example:

.. code-block:: python

    from edc_sites.site import sites
    from edc_sites.single_site import SingleSite

    suffix = "inte.clinicedc.org"

    sites.register(
        SingleSite(
            101,
            "hindu_mandal",
            title="Hindu Mandal Hospital",
            country="tanzania",
            country_code="tz",
            domain=f"hindu_mandal.tz.{suffix}",
        ),
        SingleSite(
            102,
            "amana",
            title="Amana Hospital",
            country="tanzania",
            country_code="tz",
            domain=f"amana.tz.{suffix}",
        ),
        SingleSite(
            201,
            "kojja",
            country="uganda",
            country_code="ug",
            domain=f"kojja.ug.{suffix}",
        ),
        SingleSite(
            202,
            "mbarara",
            country="uganda",
            country_code="ug",
            domain=f"mbarara.ug.{suffix}",
        ),
    )

You can use the ``sites`` global to get the trial sites for a country:

.. code-block:: python

    from edc_sites.site import sites

    In [1]: sites.get_by_country("uganda")
    Out[1]:
    {201: SingleSite(site_id=201, name='kojja', domain='kojja.ug.inte.clinicedc.org', country='uganda', description='Kojja'),
     202: SingleSite(site_id=202, name='mbarara', domain='mbarara.ug.inte.clinicedc.org', country='uganda', description='Mbarara')}


In a multisite, multi-country deployment, managing the SITE_ID is complicated. We use django_multisite_ which nicely reads
the SITE_ID from the url. django_multisite will extract `kojja` from https://kojja.ug.example.clinicedc.org to do a model lookup
to get the SITE_ID.

Viewing data from multiple sites using ``view_auditallsites``
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

The mixins provided by``edc_sites`` limit the EDC to only present data linked to the current site.
To expand access beyond the current site, ``edc_sites`` provides a special permission codename;
``view_auditallsites``. If a user has this permission, they will be shown data from the current
site plus any additional sites granted in their user profile.

The permission codename ``view_auditallsites`` cannot be allocated to a user with add/edit/delete
permissions to ANY model in the system. That is, the permission codename ``view_auditallsites``
is reserved for VIEW ONLY access, e.g the AUDITOR_ROLE. The one exception is for ``edc_auth``
and``auth`` models accessible to users granted ACCOUNT_MANAGER_ROLE permissions.

In your code, you can check if a user has access to more than just the current site using function
``may_view_other_sites``:

.. code-block:: python

    if may_view_other_sites(request):
        queryset = self.appointment_model_cls.objects.all()
    else:
        queryset = self.appointment_model_cls.on_site

To get a list of sites that the user has access to in the current request, use function
``get_view_only_site_ids_for_user``.

.. code-block:: python

    from edc_model_admin.utils import add_to_messages_once

    site_ids = get_view_only_site_ids_for_user(request.user, request.site, request=request)


Default Site and tests
++++++++++++++++++++++

Edc sites may be configured to register a default site. This may be useful for testing where
you are not registering any sites manually or through ``autodiscover``.

In ``settings``::

    EDC_SITES_REGISTER_DEFAULT=True


The default site id is 1.

If your tests depend on a test app that has a ``sites.py``, you might need to set the SITE_ID in your tests.

Use the ``override_settings`` decorator on the test class or on a specific test.

For example:

.. code-block:: python

    @override_settings(SITE_ID=20)
    class TestLpFormValidator(TestCase):
        def setUp(self):
            ...

        @override_settings(SITE_ID=40)
        def test_lp_not_done(self):
            ...




.. |pypi| image:: https://img.shields.io/pypi/v/edc-sites.svg
    :target: https://pypi.python.org/pypi/edc-sites

.. |actions| image:: https://github.com/clinicedc/edc-sites/actions/workflows/build.yml/badge.svg
  :target: https://github.com/clinicedc/edc-sites/actions/workflows/build.yml

.. |codecov| image:: https://codecov.io/gh/clinicedc/edc-sites/branch/develop/graph/badge.svg
  :target: https://codecov.io/gh/clinicedc/edc-sites

.. |downloads| image:: https://pepy.tech/badge/edc-sites
   :target: https://pepy.tech/project/edc-sites

.. _django_multisite: https://github.com/ecometrica/django-multisite.git

.. _sites_framework: https://docs.djangoproject.com/en/dev/ref/contrib/sites/
__ sites_framework_

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/clinicedc/edc-sites",
    "name": "edc-sites",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.12",
    "maintainer_email": null,
    "keywords": "django Edc sites, clinicedc, clinical trials",
    "author": "Erik van Widenfelt",
    "author_email": "ew2789@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/d8/c1/548e24b8100c76ac87885c8323ab2bec9454984115e5c31d9b96776d5ce3/edc_sites-0.3.66.tar.gz",
    "platform": null,
    "description": "|pypi| |actions| |codecov| |downloads|\n\nedc-sites\n---------\n\nSite definitions to work with Django's `Sites Framework`__ and django_multisite_.\n\nDefine a ``sites.py``. This is usually in a separate project module. For example, for project ``meta`` there is a module ``meta_sites`` that contains a ``sites.py``.\n\nRegister your sites in ``sites.py``.\n\n.. code-block:: python\n\n    # sites.py\n    from edc_sites.site import sites\n    from edc_sites.single_site import SingleSite\n\n\tsuffix = \"example.clinicedc.org\"\n\n\tsites.register(\n\t    SingleSite(\n\t        10,\n\t        \"hindu_mandal\",\n\t        title=\"Hindu Mandal Hospital\",\n\t        country=\"tanzania\",\n\t        country_code=\"tz\",\n\t        domain=f\"hindu_mandal.tz.{suffix}\",\n\t    ),\n\t    SingleSite(\n\t        20,\n\t        \"amana\",\n\t        title=\"Amana Hospital\",\n\t        country=\"tanzania\",\n\t        country_code=\"tz\",\n\t        domain=f\"amana.tz.{suffix}\",\n\t    ),\n\t)\n\n\nA ``post_migrate`` signal is registered in ``apps.py`` to update the django model ``Site`` and the\nEDC model ``SiteProfile`` on the next migration:\n\n.. code-block:: python\n\n\t# apps.py\n\n    from edc_sites.add_or_update_django_sites import add_or_update_django_sites\n\n\tdef post_migrate_update_sites(sender=None, **kwargs):\n\t    sys.stdout.write(style.MIGRATE_HEADING(\"Updating sites:\\n\"))\n\t    add_or_update_django_sites(verbose=True)\n\t    sys.stdout.write(\"Done.\\n\")\n\t    sys.stdout.flush()\n\n\n\nNow in your code you can use the ``sites`` global to inspect the trial sites:\n\n.. code-block:: python\n\n    from edc_sites.site import sites\n\n    In [1]: sites.all()\n    Out[1]:\n    {10: SingleSite(site_id=10, name='hindu_mandal', domain='hindu_mandal.tz.example.clinicedc.org', country='tanzania', description='Hindu Mandal Hospital'),\n     20: SingleSite(site_id=20, name='amana', domain='amana.tz.example.clinicedc.org', country='tanzania', description='Amana Hospital')}\n\n    In [2]: sites.get(10)\n    Out[2]: SingleSite(site_id=10, name='hindu_mandal', domain='hindu_mandal.tz.example.clinicedc.org', country='tanzania', description='Hindu Mandal Hospital')\n\n    In [3]: sites.get_by_attr(\"name\", 'hindu_mandal')\n    Out[3]: SingleSite(site_id=10, name='hindu_mandal', domain='hindu_mandal.tz.example.clinicedc.org', country='tanzania', description='Hindu Mandal Hospital')\n\n    In [4]: sites.get(10).languages\n    Out[4]:\n    {'sw': 'Swahili',\n     'en-gb': 'British English',\n     'en': 'English',\n     'mas': 'Maasai',\n     'ry': 'Runyakitara',\n     'lg': 'Ganda',\n     'rny': 'Runyankore'}\n\n\nTake a look at the ``Sites`` class in edc_sites.site for more available methods.\n\nFor another deployment, we have alot of sites spread out over a few countries.\n\nFor example:\n\n.. code-block:: python\n\n    from edc_sites.site import sites\n    from edc_sites.single_site import SingleSite\n\n    suffix = \"inte.clinicedc.org\"\n\n    sites.register(\n        SingleSite(\n            101,\n            \"hindu_mandal\",\n            title=\"Hindu Mandal Hospital\",\n            country=\"tanzania\",\n            country_code=\"tz\",\n            domain=f\"hindu_mandal.tz.{suffix}\",\n        ),\n        SingleSite(\n            102,\n            \"amana\",\n            title=\"Amana Hospital\",\n            country=\"tanzania\",\n            country_code=\"tz\",\n            domain=f\"amana.tz.{suffix}\",\n        ),\n        SingleSite(\n            201,\n            \"kojja\",\n            country=\"uganda\",\n            country_code=\"ug\",\n            domain=f\"kojja.ug.{suffix}\",\n        ),\n        SingleSite(\n            202,\n            \"mbarara\",\n            country=\"uganda\",\n            country_code=\"ug\",\n            domain=f\"mbarara.ug.{suffix}\",\n        ),\n    )\n\nYou can use the ``sites`` global to get the trial sites for a country:\n\n.. code-block:: python\n\n    from edc_sites.site import sites\n\n    In [1]: sites.get_by_country(\"uganda\")\n    Out[1]:\n    {201: SingleSite(site_id=201, name='kojja', domain='kojja.ug.inte.clinicedc.org', country='uganda', description='Kojja'),\n     202: SingleSite(site_id=202, name='mbarara', domain='mbarara.ug.inte.clinicedc.org', country='uganda', description='Mbarara')}\n\n\nIn a multisite, multi-country deployment, managing the SITE_ID is complicated. We use django_multisite_ which nicely reads\nthe SITE_ID from the url. django_multisite will extract `kojja` from https://kojja.ug.example.clinicedc.org to do a model lookup\nto get the SITE_ID.\n\nViewing data from multiple sites using ``view_auditallsites``\n+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n\nThe mixins provided by``edc_sites`` limit the EDC to only present data linked to the current site.\nTo expand access beyond the current site, ``edc_sites`` provides a special permission codename;\n``view_auditallsites``. If a user has this permission, they will be shown data from the current\nsite plus any additional sites granted in their user profile.\n\nThe permission codename ``view_auditallsites`` cannot be allocated to a user with add/edit/delete\npermissions to ANY model in the system. That is, the permission codename ``view_auditallsites``\nis reserved for VIEW ONLY access, e.g the AUDITOR_ROLE. The one exception is for ``edc_auth``\nand``auth`` models accessible to users granted ACCOUNT_MANAGER_ROLE permissions.\n\nIn your code, you can check if a user has access to more than just the current site using function\n``may_view_other_sites``:\n\n.. code-block:: python\n\n    if may_view_other_sites(request):\n        queryset = self.appointment_model_cls.objects.all()\n    else:\n        queryset = self.appointment_model_cls.on_site\n\nTo get a list of sites that the user has access to in the current request, use function\n``get_view_only_site_ids_for_user``.\n\n.. code-block:: python\n\n    from edc_model_admin.utils import add_to_messages_once\n\n    site_ids = get_view_only_site_ids_for_user(request.user, request.site, request=request)\n\n\nDefault Site and tests\n++++++++++++++++++++++\n\nEdc sites may be configured to register a default site. This may be useful for testing where\nyou are not registering any sites manually or through ``autodiscover``.\n\nIn ``settings``::\n\n    EDC_SITES_REGISTER_DEFAULT=True\n\n\nThe default site id is 1.\n\nIf your tests depend on a test app that has a ``sites.py``, you might need to set the SITE_ID in your tests.\n\nUse the ``override_settings`` decorator on the test class or on a specific test.\n\nFor example:\n\n.. code-block:: python\n\n    @override_settings(SITE_ID=20)\n    class TestLpFormValidator(TestCase):\n        def setUp(self):\n            ...\n\n        @override_settings(SITE_ID=40)\n        def test_lp_not_done(self):\n            ...\n\n\n\n\n.. |pypi| image:: https://img.shields.io/pypi/v/edc-sites.svg\n    :target: https://pypi.python.org/pypi/edc-sites\n\n.. |actions| image:: https://github.com/clinicedc/edc-sites/actions/workflows/build.yml/badge.svg\n  :target: https://github.com/clinicedc/edc-sites/actions/workflows/build.yml\n\n.. |codecov| image:: https://codecov.io/gh/clinicedc/edc-sites/branch/develop/graph/badge.svg\n  :target: https://codecov.io/gh/clinicedc/edc-sites\n\n.. |downloads| image:: https://pepy.tech/badge/edc-sites\n   :target: https://pepy.tech/project/edc-sites\n\n.. _django_multisite: https://github.com/ecometrica/django-multisite.git\n\n.. _sites_framework: https://docs.djangoproject.com/en/dev/ref/contrib/sites/\n__ sites_framework_\n",
    "bugtrack_url": null,
    "license": "GPL license, see LICENSE",
    "summary": "Simple classes related to the django sites framework for clinicedc projects",
    "version": "0.3.66",
    "project_urls": {
        "Homepage": "https://github.com/clinicedc/edc-sites"
    },
    "split_keywords": [
        "django edc sites",
        " clinicedc",
        " clinical trials"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "3d7c73ab152b08b0c781d2e28d95c3203fcfe80a583ccb6892b6a78e9b16a5cb",
                "md5": "7290247de31112e6f675fe5213401778",
                "sha256": "982a464ce455e484effc034bdb8b8d178762db96b4dbb7638ca1d87b803dfe3e"
            },
            "downloads": -1,
            "filename": "edc_sites-0.3.66-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "7290247de31112e6f675fe5213401778",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.12",
            "size": 58934,
            "upload_time": "2024-11-20T22:08:36",
            "upload_time_iso_8601": "2024-11-20T22:08:36.049662Z",
            "url": "https://files.pythonhosted.org/packages/3d/7c/73ab152b08b0c781d2e28d95c3203fcfe80a583ccb6892b6a78e9b16a5cb/edc_sites-0.3.66-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "d8c1548e24b8100c76ac87885c8323ab2bec9454984115e5c31d9b96776d5ce3",
                "md5": "4d7e87982e4fc401c5c613a58cdb04cd",
                "sha256": "7951c5a8e8838fb9088ecaaa65f1cd8c4ad70f767b2f0f16dee00019bb1afbef"
            },
            "downloads": -1,
            "filename": "edc_sites-0.3.66.tar.gz",
            "has_sig": false,
            "md5_digest": "4d7e87982e4fc401c5c613a58cdb04cd",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.12",
            "size": 50015,
            "upload_time": "2024-11-20T22:08:37",
            "upload_time_iso_8601": "2024-11-20T22:08:37.361991Z",
            "url": "https://files.pythonhosted.org/packages/d8/c1/548e24b8100c76ac87885c8323ab2bec9454984115e5c31d9b96776d5ce3/edc_sites-0.3.66.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-11-20 22:08:37",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "clinicedc",
    "github_project": "edc-sites",
    "travis_ci": false,
    "coveralls": true,
    "github_actions": true,
    "lcname": "edc-sites"
}
        
Elapsed time: 0.61796s