-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #14 from FAIR-CA-indicators/load-omex-archive
Allow for automated parsing of uploaded omex archive
- Loading branch information
Showing
51 changed files
with
757,649 additions
and
117 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# syntax=docker/dockerfile:1 | ||
|
||
FROM python:3.9 as main | ||
LABEL authors="francois.ancien" | ||
|
||
|
||
USER root | ||
WORKDIR /faircombine | ||
COPY requirements.txt /faircombine/requirements.txt | ||
RUN python3 -m pip install --no-cache-dir --upgrade -r /faircombine/requirements.txt | ||
|
||
COPY ./app /faircombine/app | ||
COPY ./app/dependencies/settings.py.template /faircombine/app/dependencies/settings.py | ||
COPY ./session_files /faicombine/session_files | ||
|
||
ENV REDIS_URL="faircombine-redis" | ||
ENV REDIS_PORT=6379 | ||
|
||
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80", "--reload"] | ||
|
||
FROM main as celery | ||
ENV BACKEND_URL="faircombine-backend" | ||
ENV BACKEND_PORT=80 | ||
CMD ["celery", "-A", "app.celery.celery_app", "worker", "-l", "INFO"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
from .f1_model_persistent_identifier_task import f1_model_persistent_identifier | ||
from .f4_model_metadata_harvestable_task import f4_model_metadata_harvestable | ||
|
||
__all__ = [ | ||
f1_model_persistent_identifier, | ||
f4_model_metadata_harvestable, | ||
] |
91 changes: 91 additions & 0 deletions
91
app/celery/automated_tasks/f1_model_persistent_identifier_task.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
import requests | ||
|
||
from typing import Optional | ||
|
||
from app.celery.celery_app import app | ||
from app.dependencies.settings import get_settings | ||
from urllib.parse import urlparse | ||
from ... import models | ||
|
||
|
||
def check_alt_ids(metadata: dict) -> bool: | ||
accepted_persistents = [ | ||
"doi.org", | ||
"purl.org", | ||
"purl.oclc.org", | ||
"purl.net", | ||
"purl.com", | ||
"identifiers.org", | ||
"w3id.org", | ||
] | ||
|
||
for resource_id in metadata["alt_ids"]: | ||
resource_url = urlparse(resource_id) | ||
if resource_url.netloc in accepted_persistents: | ||
return True | ||
|
||
return False | ||
|
||
|
||
@app.task | ||
def f1_model_persistent_identifier( | ||
task_dict: dict, data: dict, test: bool = False | ||
) -> Optional["models.TaskStatus"]: | ||
""" | ||
Representation of celery task to evaluate an assessment. | ||
These celery tasks should be in the format: | ||
``` | ||
def assessment_task(task_dict: dict, data: dict) -> None: | ||
session_id = task_dict["session_id"] | ||
task_id = task_dict["id"] | ||
# Code to get the final TaskStatus | ||
... | ||
status = models.TaskStatusIn(status=models.TaskStatus(result), force_update=config.celery_key) | ||
requests.patch( | ||
f"http://localhost:8000/session/{session_id}/tasks/{task_id}, | ||
json=status | ||
) | ||
:param task_dict: Task dict representation | ||
:param data: (Meta)Data to evaluate | ||
:return: None | ||
""" | ||
config = get_settings() | ||
print("Execution successfully called") | ||
session_id = task_dict["session_id"] | ||
task_id = task_dict["id"] | ||
try: | ||
if data["main_model_metadata"] and check_alt_ids(data["main_model_metadata"]): | ||
print("Found persistent identifiers in model metadata") | ||
result = "success" | ||
else: | ||
print("No persistent identifier was found for model") | ||
result = "failed" | ||
except Exception as e: | ||
print(f"An error occurred while assessing task: {str(e)}") | ||
result = "error" | ||
|
||
print(config.celery_key) | ||
status = models.TaskStatusIn( | ||
status=models.TaskStatus(result), force_update=config.celery_key | ||
) | ||
|
||
print(f"Task status computed: {result}") | ||
# Needs to send a request for the task to be updated | ||
if test: | ||
return models.TaskStatus(result) | ||
else: | ||
url = f"http://{config.backend_url}:{config.backend_port}/session/{session_id}/tasks/{task_id}" | ||
print(f"Patching {url}") | ||
requests.patch( | ||
url, | ||
json=status.dict(), | ||
) | ||
|
||
# Does not work because celery does not have access to fair_indicators | ||
# routers.update_task(session_id, task_id, status) | ||
|
||
# Works, but does not trigger updating of children | ||
# redis_app.json().set(f"session:{session_id}", f".tasks.{task_id}.status", obj=result) |
71 changes: 71 additions & 0 deletions
71
app/celery/automated_tasks/f4_model_metadata_harvestable_task.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import requests | ||
|
||
from typing import Optional | ||
|
||
from app.celery.celery_app import app | ||
from app.dependencies.settings import get_settings | ||
from ... import models | ||
|
||
|
||
def dict_non_empty(metadata: dict): | ||
return any([bool(x) for x in metadata.values()]) | ||
|
||
|
||
@app.task | ||
def f4_model_metadata_harvestable( | ||
task_dict: dict, data: dict, test: bool = False | ||
) -> Optional["models.TaskStatus"]: | ||
""" | ||
Representation of celery task to evaluate an assessment. | ||
These celery tasks should be in the format: | ||
``` | ||
def assessment_task(task_dict: dict, data: dict) -> None: | ||
session_id = task_dict["session_id"] | ||
task_id = task_dict["id"] | ||
# Code to get the final TaskStatus | ||
... | ||
status = models.TaskStatusIn(status=models.TaskStatus(result), force_update=config.celery_key) | ||
requests.patch( | ||
f"http://localhost:8000/session/{session_id}/tasks/{task_id}, | ||
json=status | ||
) | ||
:param task_dict: Task dict representation | ||
:param data: (Meta)Data to evaluate | ||
:return: None | ||
""" | ||
config = get_settings() | ||
print("Execution successfully called") | ||
session_id = task_dict["session_id"] | ||
task_id = task_dict["id"] | ||
|
||
if dict_non_empty(data["main_model_metadata"]): | ||
print(f"Found metadata: {data['main_model_metadata']}") | ||
result = "success" | ||
else: | ||
print("No metadata found") | ||
result = "failed" | ||
|
||
status = models.TaskStatusIn( | ||
status=models.TaskStatus(result), force_update=config.celery_key | ||
) | ||
|
||
print(f"Task status computed: {result}") | ||
if test: | ||
return models.TaskStatus(result) | ||
else: | ||
# Needs to send a request for the task to be updated | ||
url = f"http://{config.backend_url}:{config.backend_port}/session/{session_id}/tasks/{task_id}" | ||
print(f"Patching {url}") | ||
requests.patch( | ||
url, | ||
json=status.dict(), | ||
) | ||
|
||
# Does not work because celery does not have access to fair_indicators | ||
# routers.update_task(session_id, task_id, status) | ||
|
||
# Works, but does not trigger updating of children | ||
# redis_app.json().set(f"session:{session_id}", f".tasks.{task_id}.status", obj=result) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
from celery import Celery | ||
from app.dependencies.settings import get_settings | ||
|
||
config = get_settings() | ||
# FIXME Need to load broker from settings | ||
app = Celery("fair-combine", broker=config.celery_broker) | ||
app.autodiscover_tasks(["app.celery.automated_tasks"]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import inspect | ||
from typing import Type | ||
|
||
from fastapi import Form | ||
from pydantic import BaseModel | ||
from pydantic.fields import ModelField | ||
|
||
|
||
def as_form(cls: Type[BaseModel]): | ||
new_parameters = [] | ||
|
||
for field_name, model_field in cls.__fields__.items(): | ||
model_field: ModelField | ||
|
||
new_parameters.append( | ||
inspect.Parameter( | ||
model_field.alias, | ||
inspect.Parameter.POSITIONAL_ONLY, | ||
default=Form(...) | ||
if model_field.required | ||
else Form(model_field.default), | ||
annotation=model_field.outer_type_, | ||
) | ||
) | ||
|
||
def as_form_func(**params): | ||
return cls(**params) | ||
|
||
sig = inspect.signature(as_form_func) | ||
sig = sig.replace(parameters=new_parameters) | ||
as_form_func.__signature__ = sig | ||
setattr(cls, "as_form", as_form_func) | ||
return cls |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.