Exemplo n.º 1
0
def run(overlay: dict = {}):
    ''' Startet ispBaseWebApp mit zusätzlichen config Angaben

    Parameters
    ----------
    overlay : dict, optional
        Overlay Angaben für config. The default is {}.

    Returns
    -------
    webApp : ispBaseWebApp
        Die gestartete WebApplication

    '''

    # Konfiguration öffnen
    _config = ispConfig(mqttlevel=logging.WARNING)

    _apiConfig = {
        "models": [gqa, gqadb, system],
    }

    # Webserver starten
    webApp = ispBaseWebApp(_config, db, apiconfig=_apiConfig, overlay=overlay)

    #  mqtt in config schließen
    _config.mqttCleanup()
    return webApp
Exemplo n.º 2
0
    def __init__(self, variables:dict={}, autoRender:bool=True, config=None, filename: str=None ):
        """PDF vorbereiten.

        Parameters
        ----------
        variables: dict
            zum ergänzen oder ändern von config.variables
            _variables wird zum ersetzen von Schlüsselwörtern verwendet

        autoRender: bool - True
             Elemente sofort rendern oder nur zurückgeben

        config: dict oder isp config
            verwendet wird variables, templates und pdf

        filename:
            Den angegebenen Dateinamen verwenden und nicht aus den variables erzeugen

        """

        # Konfiguration
        if not config:
            self._config = ispConfig( mqttlevel=logging.WARNING )
        else:
            self._config = config

        # Defaultwerte der Klassse setzen
        self.set_class_defaults()

        # default _variables Angaben mit config.variables ergänzen
        self._variables = dict_merge( self._variables, self._config.get( "variables", {} ) )
        # zusätzliche angegebene variables ergänzen
        self._variables = dict_merge( self._variables, variables )

        # Dateiname ggf. aus den metadaten aufbereiten
        if filename:
            self._variables["filename"] = filename

        self.autoRender = autoRender

        # overlay und page layout setzen
        self.set_page_defaults()

        # plot defaults setzen
        plt.rcParams.update( rcParams )
Exemplo n.º 3
0
    def _extendedSystemCheck(self):
        """filled Stub Function for api_list (Systeminformationen)

        Returns
        -------
        dict, string

        """
        import os
        import json

        def checkPath(path, info):
            html = ""
            if os.path.exists(path):
                info_class = "success"
                info_text = "{} ist vorhanden.".format(info)
            else:
                info_class = "danger"
                info_text = "{} ist nicht vorhanden.".format(info)
            html += '<div class="alert alert-{} ">{}</div>'.format(
                info_class, info_text)

            if os.path.isdir(path):
                info_class = "success"
                info_text = "{} ist ein Verzeichnis.".format(info)
            else:
                info_class = "danger"
                info_text = "{} ist kein Verzeichnis.".format(info)
            html += '<div class="alert alert-{} ">{}</div>'.format(
                info_class, info_text)

            if os.access(path, os.W_OK):
                info_class = "success"
                info_text = "{} ist beschreibbar.".format(info)
            else:
                info_class = "danger"
                info_text = "{} ist nicht beschreibbar.".format(info)
            html += '<div class="alert alert-{} ">{}</div>'.format(
                info_class, info_text)

            return html

        config = ispConfig()
        html = "<h4>System Check</h4>"

        from isp.config import dict_merge

        # --------------- Aria Datenbank
        from app.aria import ariaClass
        _database_key = config.get("database.servername", "")

        connect = None
        aria = None

        loaded_config = config.get(["database", _database_key])
        db_config = {
            "dbname": "notset",
            "host": "notset",
            "user": "******",
            "password": "******"
        }
        if loaded_config:
            db_config = dict_merge(db_config, loaded_config.toDict())
            aria = ariaClass(_database_key, config)
            connect = aria.openDatabase(_database_key)
        else:
            html += '<div class="alert alert-danger">Kein passender Eintrag für <b>server.database.servername</b></div>'

        html += '<div class="alert alert-dark" >Prüfe Datenbankzugriff <span class="badge badge-info">database.servername</span>: <b>{}</b> - Konfiguration:'.format(
            _database_key)
        db_config_copy = db_config.copy()
        db_config_copy["password"] = "******"
        html += '</br> <pre>{}</pre>'.format(
            json.dumps(db_config_copy, indent=2))
        info_text = "Der Zugriff auf die Datenbank dbname:<b>{dbname}</b>, host:<b>{host}</b>, user:<b>{user}</b>".format(
            **db_config)
        if not connect:
            info_class = "danger"
            info_text = "{} ist nicht möglich.".format(info_text)
        else:
            info_class = "success"
            info_text = "{} ist möglich.".format(info_text)
            db_version = aria.getDbVersion()
            info_text += "<br>{}".format(
                db_version.replace("\\n", "<br>").replace('\\t', ''))

        html += '<div class="alert alert-{} ">{}</div>'.format(
            info_class, info_text)

        if connect:
            html += '<div class="alert alert-dark" >Prüfe Patienten für <span class="badge badge-info">units</span> - Konfiguration:'
            html += '</br> <pre>{}</pre>'.format(
                json.dumps(config.get("units").toDict(), indent=2))
            for name, unit in config.get("units").items():

                sql = "SELECT PatientSer, PatientId, FirstName, LastName FROM [{dbname}].[dbo].[Patient] [Patient]"
                sql = sql + " WHERE [PatientId] = '{}' ".format(name)
                result = aria.execute(sql)

                html += aria.lastExecuteSql

                info_text = "PatientId: <b>{}</b>".format(name)
                if len(result) > 0:
                    info_text = "{} ist vorhanden.".format(info_text)
                    info_text += '</br> <pre>{}</pre>'.format(
                        json.dumps(result[0], indent=2))
                    info_class = "success"
                else:
                    info_text = "{} ist nicht vorhanden.".format(info_text)
                    info_class = "danger"

                html += '<div class="alert alert-{} ">{}'.format(
                    info_class, info_text)

                if len(result) > 0:
                    html += "<br>Prüfe Tags im Datenbankfeld '[Radiation].[Comment]' für PatientId: <b>{}</b> ".format(
                        name)
                    tags = aria.getTags(name)
                    if tags and len(tags) > 0:
                        info_text = "<b>{}</b> Tags sind vorhanden.".format(
                            len(tags))
                        info_class = "success"
                    else:
                        info_text = "Keine Tags vorhanden."
                        info_class = "danger"
                    html += '<div class="alert alert-{} ">{}</div>'.format(
                        info_class, info_text)
                html += "</div>"
            html += "</div>"
        html += "</div>"

        # --------------- DICOM
        from app.ariadicom import ariaDicomClass

        _dicom_key = config.get("dicom.servername", "")
        adc = ariaDicomClass(_database_key, _dicom_key, config)

        loaded_config = config.get(["dicom", _dicom_key])

        dicom_config = {
            "aec": "notset",
            "server_ip": "notset",
            "server_port": "notset",
            "aet": "notset",
            "listen_port": "notset"
        }
        if loaded_config:
            dicom_config = dict_merge(dicom_config, loaded_config.toDict())
        else:
            html += '<div class="alert alert-danger">Kein passender Eintrag für <b>server.dicom.servername</b></div>'

        html += '<div class="alert alert-dark" >Prüfe Dicom <span class="badge badge-info">dicom.servername</span>: <b>{}</b> - Konfiguration:'.format(
            _dicom_key)
        html += '<pre>{}</pre>'.format(json.dumps(dicom_config, indent=2))
        html += '<br>Server Settings - AE Title (aec): <b>{aec}</b> - IP (server_ip): <b>{server_ip}</b> - Port (server_port): <b>{server_port}</b><br>'.format(
            **dicom_config)
        html += '<br>Application Entity Map Entry - AE Title (aet): <b>{aet}</b> - Port (listen_port): <b>{listen_port}</b>'.format(
            **dicom_config)
        html += '<div class="alert alert-dark" >Prüfe Verzeichnis: <span class="badge badge-info">dicom.{}.local_dir</span>'.format(
            _dicom_key)
        html += checkPath(
            dicom_config.get("local_dir", "notset"),
            '<span class="badge badge-info">dicom.{}.local_dir</span>'.format(
                _dicom_key))
        html += "</div>"

        status = adc.initAE()
        dicom_info = adc.getInfo()
        adc.closeAE()
        if status == 0x0000:
            info_class = "success"
            info_text = "Dicom Zugriff ist möglich. Associations: "
            for association in dicom_info["associations"]:
                association["ae_title"] = association["ae_title"].decode(
                ).strip()
                info_text += '</br> <pre>{}</pre>'.format(
                    json.dumps(association, indent=2))
        else:
            info_class = "danger"
            info_text = "Dicom Zugriff ist nicht möglich. ErrorCode: 0x{0:04x}.".format(
                status)

        html += '<div class="alert alert-{} ">{}</div>'.format(
            info_class, info_text)
        html += "</div>"

        # --------------- resultsPath
        resultsPath = adc.initResultsPath()
        html += '<div class="alert alert-dark" >Prüfe <span class="badge badge-info">resultsPath</span>: <b>{}</b>'.format(
            resultsPath)
        html += checkPath(resultsPath,
                          '<span class="badge badge-info">resultsPath</span>')
        html += "</div>"

        # --------------- MQTT
        mqtt_config = config.get("server.mqtt")
        mqtt_config_copy = mqtt_config.copy()
        mqtt_config_copy.password = "******"
        if mqtt_config_copy.get("host", "") == "":
            html += '<div class="alert alert-info" >MQTT deaktiviert'
        else:
            html += '<div class="alert alert-dark" >Prüfe <span class="badge badge-info">server.mqtt</span> - Konfiguration:'
            html += '<pre>{}</pre>'.format(
                json.dumps(mqtt_config_copy.toDict(), indent=2))

            mqtt = config.mqttGetHandler()
            if not mqtt:
                info_class = "danger"
                info_text = "MQTT Zugriff ist nicht möglich."
            else:
                info_class = "info"
                info_text = 'MQTT Zugriff ist eingerichtet. <button type="button" class="btn btn-primary" onClick="mqttTest( this )">Prüfen</button>'

            html += '<div id="MQTT-checkline" class="alert alert-{} ">{}<div id="MQTT-results" class"alert"></div></div>'.format(
                info_class, info_text)

        html += "</div>"
        html += '''
            <script>
            var box = document.querySelector("#MQTT-checkline");
            var result_box = document.querySelector("#MQTT-results");
            if ( typeof app.clientMqtt === "object" ) {
                app.clientMqtt.subscribe( "MQTT/test", function( msg ) {
                    box.className = "alert alert-success";
                    result_box.className = "alert alert-success";
                    result_box.innerHTML = "MQTT Test erfolgreich";
                } );
            }
            function mqttTest( btn ){
                box.className = "alert alert-info";
                result_box.className = "";

                if ( typeof app.clientMqtt === "object" ) {
                    result_box.className = "alert alert-danger";
                    result_box.innerHTML = "MQTT Test nicht erfolgreich.";
                    app.clientMqtt.publish( "MQTT/test", { "test":"MQTT" } );
                } else {
                    result_box.className = "alert alert-warning";
                    result_box.innerHTML = "kein clientMqtt vorhanden";
                }
            }
            </script>
        '''
        return {}, html
Exemplo n.º 4
0
    def __init__(self,
                 config=None,
                 db=None,
                 name: str = None,
                 webconfig=None,
                 apiconfig=None,
                 overlay: dict = {}):
        """Erzeugt die Flask App.

        ruft _create_app auf um die Datenbank Api bereitzustellen.

        Parameters
        ----------
        config : ispConfig
            geladene config mit server.webserver und server.api
        db: SQLAlchemy
            Initialisiertes SQLAlchemy Object - db=SQLAlchemy()
        name: str
            Name der connection aus config.database.<name>.connection
        webconfig : dot|dict
            überschreibt ggf. die Inhalte aus config.server.webserver
        apiconfig : dot|dict
            überschreibt ggf. die Inhalte aus config.server.api
        overlay : dict
            überschreibt die Inhalte der config z.B. für unittest
            Verwenden von Overlay::

                from flask import current_app
                print( current_app._configOverlay )

        Returns
        -------
        None.
        """
        if config == None:
            config = ispConfig(
                config={
                    "server": {
                        "webserver": {
                            "TESTING": True,
                            "SECRET_KEY": os.urandom(16)
                        }
                    }
                })
        elif not isinstance(config, ispConfig):
            # config immer als ispConfig, dies lädt keine config daten sondern verwendet die angegebenen
            config = ispConfig(config=config)

        # overlay merken und config updaten
        self._configOverlay = overlay
        config.update(overlay)

        # in self._config merken
        self._config = config

        # keys für contentparameter
        self._urlContentParamsKey = '_ispcp'

        self._headerContentParamsKey = 'X-ISP-CONTENT-PARAMS'

        # default status code für templates (routeIndex)
        self.status_code = 200

        # default status code für templates (routeIndex)
        self.default_header = {'Content-Type': 'text/html; charset=utf-8'}

        #
        # webserver konfiguration aus config.server erweitern
        #
        if webconfig:
            self._config.merge("server.webserver", webconfig)
        #
        # api konfiguration aus config.server erweitern
        #
        if apiconfig:
            self._config.merge("server.api", apiconfig)

        #
        # Hauptdatenbank festlegen
        #
        db_names = []
        db_binds = {}
        # name für die Main Datenbank
        if not name:
            name = self._config.get("database.main", [])

            if type(name) == str:
                db_names.append(name)
            elif type(name) == list:
                db_names = name

            for name in db_names:
                # versuchen eine passende datenbank config zu finden, wenn ja diese verwenden
                #db_uri = self._config.get("database." + name + ".connection", "").format( **{"BASE_DIR": self._config.BASE_DIR } )
                db_binds[name] = self._config.get("database." + name +
                                                  ".connection",
                                                  "",
                                                  replaceVariables=True)

        #
        # App erzeugen mit SQLAlchemy() und DatabaseUri
        #
        app = self._create_app(db, db_binds)

        # logger für safrs
        log.setLevel(self._config.get("server.logging.safrs",
                                      logging.WARNING))  # logging.DEBUG

        # logger für sqlalchemy
        sql_logger = logging.getLogger("sqlalchemy")
        sql_logger.setLevel(
            self._config.get("server.logging.sqlalchemy", logging.WARNING))

        # app starten
        if app:
            # template_folder auf ui setzen wird bei routeRender verwendet
            app.template_folder = osp.join(self._config.BASE_DIR, "ui")

            # wenn gewünscht dbadmin interface bereitstellen
            #
            # wird in der klasse no_flask_admin=True angegeben wird für diese admin Interface eingebunden
            if self._config.get("server.api.DBADMIN", False):

                # see if we can add the flask-admin views
                try:
                    from flask_admin import Admin
                    from flask_admin.contrib import sqla
                except Exception as exc:  # pragma: no cover
                    print(f"flask-admin import failed {exc}")
                models = self._config.get("server.api.models", [])
                try:
                    admin = Admin(app, url="/dbadmin")
                    for model in models:
                        if hasattr(model, "no_flask_admin"
                                   ) and model.no_flask_admin == True:
                            pass
                        else:
                            admin.add_view(sqla.ModelView(model, db.session))
                except Exception as exc:  # pragma: no cover
                    print(f"Failed to add flask-admin view {exc}")

            # app.logger für flask
            app.logger.setLevel(
                self._config.get("server.logging.webapp", logging.WARNING))

            # Modus festlegen
            mode = "APP"
            if self._config.get("server.webserver.TESTING"):
                mode = "TESTING"

            self.apiurl = "http://{}:{}{}".format(
                self._config.get("server.webserver.host"),
                self._config.get("server.webserver.port"),
                self._config.get("server.api.prefix", ""))
            # Webserver startparameter anzeigen
            print("Starting '{}' in '{}' Mode".format(self.apiurl, mode))
            #return
            if mode == "TESTING":
                # im testing mode  starten
                self.app = self.app.test_client()

            else:  # pragma: no cover
                # add CORS support
                # Content-Range wird von dstore ausgewertet um die max Anzahl zu bestimmen
                CORS(
                    self.app,
                    expose_headers=
                    'Content-Range, Content-Newitem,  X-Query, X-Rquery, X_Error, X_Info'
                )

                # dieser abschnitt wird bei coverage nicht berücksichtigt, da er im testmode nicht ausgeführt wird
                # nach dem starten der app wird folgender code erst nach dem beenden ausgeführt

                app.run(
                    host=self._config.get("server.webserver.host"),
                    port=self._config.get("server.webserver.port"),
                    use_reloader=self._config.get("server.webserver.reloader"),
                    threaded=False,
                    debug=self._config.get("server.webserver.debug"))
Exemplo n.º 5
0
           
        #print('Main    : {}% done...'.format(progress))
        
        #print('Main    : The result is', result)
        #print('Main    : The mq result is', hex( mq.get() ) )
        
        #print("Main    : all done")
        return result, signals
 

# -----------------------------------------------------------------------------    
if __name__ == '__main__':
    
    # Dicomdaten holen, diese werden in self.dicomData ergänzt um AcquisitionYear abgelegt
    from isp.config import ispConfig
    config = ispConfig(  )
    
    print( config.dicom.toDict() )
    dicom = dicomClass("VMSDBD", config )
    
    print( "dicomPath", dicom.dicomPath )
    
    # holen ohne override
    result1, signals = dicom.retrieve( { 
                "PatientID" : '_xxxQA TB', 
                "SOPInstanceUID" : '1.2.246.352.62.1.4625604914426170283.12140466054276070541',
                "override" : False
        } )
    
    print( "result-1:", result1, signals )
    
Exemplo n.º 6
0
    def init(self, kwargs: dict = {}):
        """
        Wird von den @jsonapi_rpc Funktionen aufgerufen

        Parameters
        ----------
        kwargs : dict, optional
            DESCRIPTION. The default is {}.

        Returns
        -------
        kwargs : TYPE
            DESCRIPTION.

        """

        info = {}
        # Konfiguration ggf. für weitere Module jahres/monats basiert bereitstellen
        # dabei kwargs immer als int wenn nicht vorhanden dann aktuelles datum
        if "year" in kwargs or "month" in kwargs or "day" in kwargs:
            year = 9999
            month = 99
            day = 99
            if "year" in kwargs:
                if kwargs["year"] == None:
                    kwargs["year"] = 0
                else:
                    kwargs["year"] = int(kwargs["year"])
                    year = kwargs["year"]
            if "month" in kwargs:
                if kwargs["month"] == None:
                    kwargs["month"] = 0
                else:
                    kwargs["month"] = int(kwargs["month"])
                    month = kwargs["month"]
            if "day" in kwargs:
                if kwargs["day"] == None:
                    kwargs["day"] = 0
                else:
                    kwargs["day"] = int(kwargs["day"])
                    day = kwargs["day"]

            last = int("{year:04d}{month:02d}{day:02d}".format(year=year,
                                                               month=month,
                                                               day=day))
            # bis last als Overlay verwenden
            self.config = ispConfig(lastOverlay=last)
            info["gqa.lastOverlay"] = last
        else:
            self.config = ispConfig()

        # config mit overlay erweitern
        self.config.update(self._configOverlay)

        info["version"] = self.config.get("version")
        info["configs"] = self.config._configs
        self.appInfo("gqa.config info", info)

        # name der verwendeten Datenbank und dicom verbindung
        self._database_key = self.config.get("server.database.servername",
                                             "VMSCOM")
        self._dicom_key = self.config.get("dicom.servername", "")

        # ariaDicom bereitstellen
        self.ariaDicom = ariaDicomClass(database=self._database_key,
                                        server=self._dicom_key,
                                        config=self.config)

        # unit pid über config Angaben holen
        if not "pid" in kwargs or kwargs["pid"] == None:
            kwargs["pid"] = list(self.config.units.keys())

        if type(kwargs["pid"]) == str:
            kwargs["pid"] = kwargs["pid"].split(",")

        # passende pid ( PatientenID ) zu einer unit über config bestimmen
        if "unit" in kwargs:
            for pid, unit in self.config.units.items():
                if unit == kwargs["unit"]:
                    kwargs["pid"] = [pid]

        self.appInfo("gqa.init", kwargs)

        return kwargs