Skip to content

signals#

LegacyUpdateFailed#

Bases: APIException

Source code in src/apps/core/signals.py
class LegacyUpdateFailed(exceptions.APIException):
    status_code = status.HTTP_409_CONFLICT

handle_files_changed#

Source code in src/apps/core/signals.py
@receiver(m2m_changed, sender=FileSet.files.through)
def handle_files_changed(sender, instance: FileSet, action, **kwargs):
    if instance.skip_files_m2m_changed:  # allow skipping handler
        return

    if action in ("post_remove", "post_clear"):
        instance.remove_unused_file_metadata()

delete_dataset_from_v2#

Sync Metax V2 when deleting dataset from v3

Source code in src/apps/core/signals.py
@receiver(post_delete, sender=Dataset)
def delete_dataset_from_v2(sender, instance: Dataset, **kwargs):
    """Sync Metax V2 when deleting dataset from v3"""
    if not settings.METAX_V2_INTEGRATION_ENABLED:
        return

    params = {"removed": "true", "hard": "true"}

    if "soft" in kwargs and kwargs["soft"] is True:
        params["hard"] = None

    host, headers = get_v2_request_settings()
    res = requests.delete(url=f"{host}/{instance.id}", headers=headers, params=params)

    if res.status_code <= 204:
        logger.info(f"response form metax v2: {res}")
        return

    logger.warning(f"Syncing data with Metax v2 did not work properly: {res.content=}")

fetch_dataset_from_v2#

Source code in src/apps/core/signals.py
def fetch_dataset_from_v2(pid: str):
    host, headers = get_v2_request_settings()
    return requests.get(url=f"{host}?preferred_identifier={pid}", headers=headers)

get_v2_request_settings#

Source code in src/apps/core/signals.py
def get_v2_request_settings():
    host = f"{settings.METAX_V2_HOST}/rest/v2/datasets"
    headers = urllib3.make_headers(
        basic_auth=f"{settings.METAX_V2_USER}:{settings.METAX_V2_PASSWORD}",
    )
    headers["Content-Type"] = "application/json"
    headers["Accept"] = "application/json"
    return host, headers

json_serial#

JSON serializer for objects not serializable by default json code

Source code in src/apps/core/signals.py
def json_serial(obj):
    """JSON serializer for objects not serializable by default json code"""
    if isinstance(obj, (datetime, date)):
        return obj.isoformat()
    raise TypeError("Type %s not serializable" % type(obj))

update_dataset_in_v2#

Source code in src/apps/core/signals.py
def update_dataset_in_v2(dataset: Dataset, created=False):
    if not settings.METAX_V2_INTEGRATION_ENABLED:
        return

    if dataset.state != "published" or dataset.removed or dataset.api_version < 3:
        return

    v2_dataset = dataset.as_v2_dataset()
    identifier = v2_dataset["identifier"]

    host, headers = get_v2_request_settings()

    found = False
    if not created:
        response = requests.get(url=f"{host}/{identifier}", headers=headers)
        found = response.status_code == 200

    res: requests.Response
    body = json.dumps(v2_dataset, cls=DjangoJSONEncoder)
    if found:
        res = requests.put(
            url=f"{host}/{identifier}?migration_override", data=body, headers=headers
        )
    else:
        res = requests.post(url=f"{host}?migration_override", data=body, headers=headers)
    if res.status_code in {200, 201}:
        logger.info(f"Sync {identifier} to V2: {res.status_code=}")
    else:
        logger.error(
            f"Sync {identifier} to V2 failed: {res.status_code=}:\n  {res.content=}, \n  {res.headers=}"
        )
        raise LegacyUpdateFailed(f"Failed to sync dataset ({identifier}) to Metax V2")

handle_dataset_updated#

Source code in src/apps/core/signals.py
@receiver(dataset_updated)
def handle_dataset_updated(sender, data: Dataset, **kwargs):
    update_dataset_in_v2(data)

handle_dataset_created#

Source code in src/apps/core/signals.py
@receiver(dataset_created)
def handle_dataset_created(sender, data: Dataset, **kwargs):
    update_dataset_in_v2(data, created=True)