mirror of
https://github.com/sartography/cr-connect-workflow.git
synced 2025-02-20 11:48:16 +00:00
Adding a simple endpoint that describes what scripts are currently available, along with a brief description.
This commit is contained in:
parent
7194d7d374
commit
94f828dfd6
25
crc/api.yml
25
crc/api.yml
@ -680,7 +680,21 @@ paths:
|
|||||||
type: string
|
type: string
|
||||||
format: binary
|
format: binary
|
||||||
example: '<?xml version="1.0" encoding="UTF-8"?><bpmn:definitions></bpmn:definitions>'
|
example: '<?xml version="1.0" encoding="UTF-8"?><bpmn:definitions></bpmn:definitions>'
|
||||||
|
/list_scripts:
|
||||||
|
get:
|
||||||
|
operationId: crc.api.tools.list_scripts
|
||||||
|
summary: Returns an list of scripts, along with their descriptions
|
||||||
|
tags:
|
||||||
|
- Configurator Tools
|
||||||
|
responses:
|
||||||
|
'201':
|
||||||
|
description: The list of scripts
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: "#/components/schemas/Script"
|
||||||
components:
|
components:
|
||||||
schemas:
|
schemas:
|
||||||
User:
|
User:
|
||||||
@ -969,3 +983,12 @@ components:
|
|||||||
message:
|
message:
|
||||||
type: string
|
type: string
|
||||||
example: "You do not have permission to view the requested study."
|
example: "You do not have permission to view the requested study."
|
||||||
|
Script:
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
format: string
|
||||||
|
example: "random_fact"
|
||||||
|
description:
|
||||||
|
type: string
|
||||||
|
example: "Returns a random fact about a topic. Provide an argument of either 'cat', 'norris', or 'buzzword'"
|
||||||
|
@ -1,18 +1,14 @@
|
|||||||
import io
|
import io
|
||||||
import json
|
import json
|
||||||
import uuid
|
|
||||||
from io import BytesIO
|
|
||||||
|
|
||||||
import connexion
|
import connexion
|
||||||
import jinja2
|
|
||||||
from docxtpl import DocxTemplate
|
|
||||||
from flask import send_file
|
from flask import send_file
|
||||||
from jinja2 import Template, UndefinedError
|
from jinja2 import Template, UndefinedError
|
||||||
|
|
||||||
from crc.api.common import ApiError, ApiErrorSchema
|
from crc.api.common import ApiError
|
||||||
from crc.scripts.complete_template import CompleteTemplate
|
from crc.scripts.complete_template import CompleteTemplate
|
||||||
from crc.services.file_service import FileService
|
from crc.scripts.script import Script
|
||||||
|
import crc.scripts
|
||||||
|
|
||||||
def render_markdown(data, template):
|
def render_markdown(data, template):
|
||||||
"""
|
"""
|
||||||
@ -48,3 +44,17 @@ def render_docx(data):
|
|||||||
raise ApiError(code="invalid", message=str(e))
|
raise ApiError(code="invalid", message=str(e))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise ApiError(code="invalid", message=str(e))
|
raise ApiError(code="invalid", message=str(e))
|
||||||
|
|
||||||
|
|
||||||
|
def list_scripts():
|
||||||
|
"""Provides a list of scripts that can be called by a script task."""
|
||||||
|
scripts = Script.get_all_subclasses()
|
||||||
|
script_meta = []
|
||||||
|
for script_class in scripts:
|
||||||
|
script_meta.append(
|
||||||
|
{
|
||||||
|
"name": script_class.__name__,
|
||||||
|
"description": script_class().get_description()
|
||||||
|
})
|
||||||
|
return script_meta
|
||||||
|
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
import requests
|
|
||||||
|
|
||||||
|
|
||||||
class IRBDocAPI:
|
|
||||||
"""Just your basic class that can pull in data from a few api endpoints and do a basic task."""
|
|
||||||
|
|
||||||
def do_task(self, task_data):
|
|
||||||
print('*** IRB_Doc_API > do_task ***')
|
|
||||||
print('task_data', task_data)
|
|
@ -17,11 +17,8 @@ from crc.services.workflow_processor import WorkflowProcessor
|
|||||||
class CompleteTemplate(Script):
|
class CompleteTemplate(Script):
|
||||||
|
|
||||||
def get_description(self):
|
def get_description(self):
|
||||||
return
|
return """Takes one argument, which is the name of a MS Word docx file to use as a template.
|
||||||
"""Completes a word template, using the data available in the current task. Heavy on the
|
All data currently collected up to this Task will be available for use in the template."""
|
||||||
error messages, because there is so much that can go wrong here, and we want to provide
|
|
||||||
as much feedback as possible. Some of this might move up to a higher level object or be
|
|
||||||
passed into all tasks as we complete more work."""
|
|
||||||
|
|
||||||
def do_task(self, task, study_id, *args, **kwargs):
|
def do_task(self, task, study_id, *args, **kwargs):
|
||||||
"""Entry point, mostly worried about wiring it all up."""
|
"""Entry point, mostly worried about wiring it all up."""
|
||||||
|
@ -5,7 +5,8 @@ from crc.scripts.script import Script
|
|||||||
|
|
||||||
class FactService(Script):
|
class FactService(Script):
|
||||||
def get_description(self):
|
def get_description(self):
|
||||||
return """Just your basic class that can pull in data from a few api endpoints and do a basic task."""
|
return """Just your basic class that can pull in data from a few api endpoints and
|
||||||
|
do a basic task."""
|
||||||
|
|
||||||
def get_cat(self):
|
def get_cat(self):
|
||||||
response = requests.get('https://cat-fact.herokuapp.com/facts/random')
|
response = requests.get('https://cat-fact.herokuapp.com/facts/random')
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
import importlib
|
||||||
|
import os
|
||||||
|
import pkgutil
|
||||||
|
|
||||||
from crc.api.common import ApiError
|
from crc.api.common import ApiError
|
||||||
|
|
||||||
|
|
||||||
@ -13,3 +17,25 @@ class Script:
|
|||||||
raise ApiError("invalid_script",
|
raise ApiError("invalid_script",
|
||||||
"This is an internal error. The script you are trying to execute " +
|
"This is an internal error. The script you are trying to execute " +
|
||||||
"does not properly implement the do_task function.")
|
"does not properly implement the do_task function.")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_all_subclasses():
|
||||||
|
return Script._get_all_subclasses(Script)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _get_all_subclasses(cls):
|
||||||
|
|
||||||
|
# hackish mess to make sure we have all the modules loaded for the scripts
|
||||||
|
pkg_dir = os.path.dirname(__file__)
|
||||||
|
for (module_loader, name, ispkg) in pkgutil.iter_modules([pkg_dir]):
|
||||||
|
importlib.import_module('.' + name, __package__)
|
||||||
|
|
||||||
|
|
||||||
|
"""Returns a list of all classes that extend this class."""
|
||||||
|
all_subclasses = []
|
||||||
|
|
||||||
|
for subclass in cls.__subclasses__():
|
||||||
|
all_subclasses.append(subclass)
|
||||||
|
all_subclasses.extend(Script._get_all_subclasses(subclass))
|
||||||
|
|
||||||
|
return all_subclasses
|
@ -13,8 +13,7 @@ class StudyInfo(Script):
|
|||||||
type_options = ['info', 'investigators', 'required_docs', 'details']
|
type_options = ['info', 'investigators', 'required_docs', 'details']
|
||||||
|
|
||||||
def get_description(self):
|
def get_description(self):
|
||||||
return """
|
return """StudyInfo [TYPE], where TYPE is one of 'info', 'investigators','required_docs', or 'details'
|
||||||
StudyInfo [TYPE] is one of 'info', 'investigators','required_docs', 'details'
|
|
||||||
Adds details about the current study to the Task Data. The type of information required should be
|
Adds details about the current study to the Task Data. The type of information required should be
|
||||||
provided as an argument. Basic returns the basic information such as the title. Investigators provides
|
provided as an argument. Basic returns the basic information such as the title. Investigators provides
|
||||||
detailed information about each investigator in th study. Details provides a large number
|
detailed information about each investigator in th study. Details provides a large number
|
||||||
|
@ -32,3 +32,11 @@ class TestStudyApi(BaseTest):
|
|||||||
data=file_data, follow_redirects=True,
|
data=file_data, follow_redirects=True,
|
||||||
content_type='multipart/form-data')
|
content_type='multipart/form-data')
|
||||||
self.assert_success(rv)
|
self.assert_success(rv)
|
||||||
|
|
||||||
|
def test_list_scripts(self):
|
||||||
|
rv = self.app.get('/v1.0/list_scripts')
|
||||||
|
self.assert_success(rv)
|
||||||
|
scripts = json.loads(rv.get_data(as_text=True))
|
||||||
|
self.assertTrue(len(scripts) > 1)
|
||||||
|
self.assertIsNotNone(scripts[0]['name'])
|
||||||
|
self.assertIsNotNone(scripts[0]['description'])
|
||||||
|
Loading…
x
Reference in New Issue
Block a user