Example #1
0
    def list(self, request, *args, **kwargs):
        # can modify result by interrogating `request.version`

        data, st = queryLedger({
            'args': '{"Args":["queryAlgos"]}'
        })

        modelData = None

        # init list to return
        if data is None:
            data = []
        l = [data]

        if st == 200:

            # parse filters
            query_params = request.query_params.get('search', None)

            if query_params is not None:
                try:
                    filters = get_filters(query_params)
                except Exception as exc:
                    return Response(
                        {'message': f'Malformed search filters {query_params}'},
                        status=status.HTTP_400_BAD_REQUEST)
                else:
                    # filtering, reinit l to empty array
                    l = []
                    for idx, filter in enumerate(filters):
                        # init each list iteration to data
                        l.append(data)
                        for k, subfilters in filter.items():
                            if k == 'algo':  # filter by own key
                                for key, val in subfilters.items():
                                    l[idx] = [x for x in l[idx] if x[key] in val]
                            elif k == 'model':  # select objectives used by outModel hash
                                if not modelData:
                                    # TODO find a way to put this call in cache
                                    modelData, st = queryLedger({
                                        'args': '{"Args":["queryTraintuples"]}'
                                    })
                                    if st != status.HTTP_200_OK:
                                        return Response(modelData, status=st)
                                    if modelData is None:
                                        modelData = []

                                for key, val in subfilters.items():
                                    filteredData = [x for x in modelData if x['outModel'] is not None and x['outModel'][key] in val]
                                    algoKeys = [x['algo']['hash'] for x in filteredData]
                                    l[idx] = [x for x in l[idx] if x['key'] in algoKeys]

        return Response(l, status=st)
Example #2
0
    def files(self, request, *args, **kwargs):
        # fetch algo from ledger
        org = conf['orgs']['chu-nantes']
        peer = org['peers'][0]

        lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field
        pk = self.kwargs[lookup_url_kwarg]

        try:
            # try to get it from local db
            instance = self.get_object()
        except Http404:
            # get instance from remote node
            algo, st = queryLedger({
                'org':
                org,
                'peer':
                peer,
                'args':
                '{"Args":["queryObject","' + pk + '"]}'
            })
        finally:
            # TODO if requester has permission, return instance
            pass

        serializer = self.get_serializer(instance)
        return Response(serializer.data['algo'])
    def list(self, request, *args, **kwargs):
        # can modify result by interrogating `request.version`

        data, st = queryLedger({'args': '{"Args":["queryTesttuples"]}'})

        data = data if data else []

        return Response(data, status=st)
Example #4
0
    def details(self, request, *args, **kwargs):
        lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field
        pk = self.kwargs[lookup_url_kwarg]

        data, st = queryLedger({
            'args': f'{{"Args":["queryModelDetails", "{pk}"]}}'
        })

        return Response(data, st)
Example #5
0
    def leaderboard(self, request, *args, **kwargs):

        # using chu-nantes as in our testing owkin has been revoked
        org = conf['orgs']['chu-nantes']
        peer = org['peers'][0]

        lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field
        pk = self.kwargs[lookup_url_kwarg]

        try:
            # try to get it from local db
            instance = self.get_object()
        except Http404:
            # get instance from remote node
            problem, st = queryLedger({
                'org':
                org,
                'peer':
                peer,
                'args':
                '{"Args":["queryObject","' + pk + '"]}'
            })

            # TODO check hash

            # TODO save problem in local db for later use
            #instance = Problem.objects.create(description=problem['description'], metrics=problem['metrics'])
        finally:
            # TODO query list of algos and models from ledger
            algos, _ = self.queryLedger({
                'org':
                org,
                'peer':
                peer,
                'args':
                '{"Args":["queryObjects", "algo"]}'
            })
            models, _ = self.queryLedger({
                'org':
                org,
                'peer':
                peer,
                'args':
                '{"Args":["queryObjects", "model"]}'
            })
            # TODO sort algos given the best perfs of their models

            # TODO return success, problem info, sorted algo + models

            #serializer = self.get_serializer(instance)
            return Response({
                'problem': problem,
                'algos': [x for x in algos if x['problem'] == pk],
                'models': models
            })
Example #6
0
def prepareTask(tuple_type, model_type):
    from django_celery_results.models import TaskResult

    try:
        data_owner = get_hash(settings.LEDGER['signcert'])
    except Exception as e:
        logging.error(e, exc_info=True)
    else:
        subtuples, st = queryLedger({
            'args':
            f'{{"Args":["queryFilter","{tuple_type}~worker~status","{data_owner},todo"]}}'
        })

        if st == status.HTTP_200_OK and subtuples is not None:
            for subtuple in subtuples:

                fltask = None
                worker_queue = f"{settings.LEDGER['name']}.worker"

                if 'fltask' in subtuple and subtuple['fltask']:
                    fltask = subtuple['fltask']
                    flresults = TaskResult.objects.filter(
                        task_name='substrapp.tasks.computeTask',
                        result__icontains=f'"fltask": "{fltask}"')

                    if flresults and flresults.count() > 0:
                        worker_queue = json.loads(
                            flresults.first().as_dict()['result'])['worker']

                try:
                    # Log Start of the Subtuple
                    start_type = 'logStartTrain' if tuple_type == 'traintuple' else 'logStartTest' if tuple_type == 'testtuple' else None
                    data, st = invokeLedger(
                        {
                            'args':
                            f'{{"Args":["{start_type}","{subtuple["key"]}"]}}'
                        },
                        sync=True)

                    if st not in (status.HTTP_201_CREATED,
                                  status.HTTP_408_REQUEST_TIMEOUT):
                        logging.error(
                            f'Failed to invoke ledger on prepareTask {tuple_type}. Error: {data}'
                        )
                    else:
                        computeTask.apply_async(
                            (tuple_type, subtuple, model_type, fltask),
                            queue=worker_queue)

                except Exception as e:
                    error_code = compute_error_code(e)
                    logging.error(error_code, exc_info=True)
                    return fail(subtuple['key'], error_code, tuple_type)
Example #7
0
    def list(self, request, *args, **kwargs):

        # using chu-nantes as in our testing owkin has been revoked
        org = conf['orgs']['chu-nantes']
        peer = org['peers'][0]

        data, st = queryLedger({
            'org': org,
            'peer': peer,
            'args': '{"Args":["queryObjects", "algo"]}'
        })

        return Response(data, status=st)
Example #8
0
def getObjectFromLedger(pk, query):
    # get instance from remote node
    data, st = queryLedger({'args': f'{{"Args":["{query}","{pk}"]}}'})

    if st == status.HTTP_404_NOT_FOUND:
        raise Http404('Not found')

    if st != status.HTTP_200_OK:
        raise JsonException(data)

    if 'permissions' not in data or data['permissions'] == 'all':
        return data
    else:
        raise Exception('Not Allowed')
Example #9
0
    def list(self, request, *args, **kwargs):

        # can modify result by interrogating `request.version`

        # using chu-nantes as in our testing owkin has been revoked
        org = conf['orgs']['chu-nantes']
        peer = org['peers'][0]

        data, st = queryLedger({
            'org': org,
            'peer': peer,
            'args': '{"Args":["queryObjects", "problem"]}'
        })

        return Response(data, status=st)
    def create(self, request, *args, **kwargs):
        # TODO update
        '''
        curl -H "Accept: text/html;version=0.0, */*;version=0.0"
             -d "algo_key=da58a7a29b549f2fe5f009fb51cce6b28ca184ec641a0c1db075729bb266549b&model_key=10060f1d9e450d98bb5892190860eee8dd48594f00e0e1c9374a27c5acdba568&train_data_keys[]=62fb3263208d62c7235a046ee1d80e25512fe782254b730a9e566276b8c0ef3a&train_data[]=42303efa663015e729159833a12ffb510ff92a6e386b8152f90f6fb14ddc94c9"
             -X POST http://localhost:8001/traintuple/

        or

        curl -H "Accept: text/html;version=0.0, */*;version=0.0"
             -H "Content-Type: application/json"
             -d '{"algo_key":"da58a7a29b549f2fe5f009fb51cce6b28ca184ec641a0c1db075729bb266549b","model_key":"10060f1d9e450d98bb5892190860eee8dd48594f00e0e1c9374a27c5acdba568","train_data_keys":["62fb3263208d62c7235a046ee1d80e25512fe782254b730a9e566276b8c0ef3a","42303efa663015e729159833a12ffb510ff92a6e386b8152f90f6fb14ddc94c9"]}'
             -X POST http://localhost:8001/traintuple/?format=json

        :param request:
        :return:
        '''

        traintuple_key = request.data.get(
            'traintuple_key', request.POST.get('traintuple_key', None))
        data_manager_key = request.data.get(
            'data_manager_key', request.POST.get('data_manager_key', ''))
        tag = request.data.get('tag', request.POST.get('tag', ''))

        try:
            test_data_sample_keys = request.data.getlist(
                'test_data_sample_keys', [])
        except:
            test_data_sample_keys = request.data.get(
                'test_data_sample_keys',
                request.POST.getlist('test_data_sample_keys', []))

        data = {
            'traintuple_key': traintuple_key,
            'data_manager_key': data_manager_key,
            'test_data_sample_keys':
            test_data_sample_keys,  # list of test data keys
            'tag': tag
        }

        # init ledger serializer
        serializer = self.get_serializer(data=data)
        serializer.is_valid(raise_exception=True)

        # Get testtuple pkhash of the proposal with a queryLedger in case of 408 timeout
        args = serializer.get_args(serializer.validated_data)
        data, st = queryLedger(
            {'args': '{"Args":["createTesttuple", ' + args + ']}'})
        if st == status.HTTP_200_OK:
            pkhash = data.get('key', data.get('keys'))
        else:
            # If queryLedger fails, invoke will fail too so we handle the issue right now
            try:
                data['message'] = data['message'].split('Error')[-1]
                msg = json.loads(
                    data['message'].split('payload:')[-1].strip().strip(
                        '"').encode('utf-8').decode('unicode_escape'))
                pkhash = msg['error'].replace('(', '').replace(
                    ')', '').split('tkey: ')[-1].strip()

                if len(pkhash) != 64:
                    raise Exception('bad pkhash')
                else:
                    st = status.HTTP_409_CONFLICT

                return Response(
                    {
                        'message': data['message'].split('payload')[0],
                        'pkhash': pkhash
                    },
                    status=st)
            except:
                return Response(data, status=st)

        # create on ledger
        data, st = serializer.create(serializer.validated_data)

        if st == status.HTTP_408_REQUEST_TIMEOUT:
            return Response({
                'message': data['message'],
                'pkhash': pkhash
            },
                            status=st)

        if st not in (status.HTTP_201_CREATED, status.HTTP_202_ACCEPTED):
            try:
                data['message'] = data['message'].split('Error')[-1]
                msg = json.loads(
                    data['message'].split('payload:')[-1].strip().strip(
                        '"').encode('utf-8').decode('unicode_escape'))
                pkhash = msg['error'].replace('(', '').replace(
                    ')', '').split('tkey: ')[-1].strip()

                if len(pkhash) != 64:
                    raise Exception('bad pkhash')
                else:
                    st = status.HTTP_409_CONFLICT

                return Response(
                    {
                        'message': data['message'].split('payload')[0],
                        'pkhash': pkhash
                    },
                    status=st)
            except:
                return Response(data, status=st)

        headers = self.get_success_headers(serializer.data)
        return Response(data, status=st, headers=headers)
Example #11
0
    def list(self, request, *args, **kwargs):
        # can modify result by interrogating `request.version`

        data, st = queryLedger({
            'args': '{"Args":["queryModels"]}'
        })
        algoData = None
        objectiveData = None
        dataManagerData = None

        # init list to return
        if data is None:
            data = []
        l = [data]

        if st == 200:
            # parse filters
            query_params = request.query_params.get('search', None)

            if query_params is not None:
                try:
                    filters = get_filters(query_params)
                except Exception as exc:
                    return Response(
                        {'message': f'Malformed search filters {query_params}'},
                        status=status.HTTP_400_BAD_REQUEST)
                else:
                    # filtering, reinit l to empty array
                    l = []
                    for idx, filter in enumerate(filters):
                        # init each list iteration to data
                        if data is None:
                            data = []
                        l.append(data)
                        for k, subfilters in filter.items():
                            if k == 'model':  # filter by own key
                                for key, val in subfilters.items():
                                    l[idx] = [x for x in l[idx] if x['traintuple']['outModel'] is not None and x['traintuple']['outModel']['hash'] in val]
                            elif k == 'algo':  # select model used by these algo
                                if not algoData:
                                    # TODO find a way to put this call in cache
                                    algoData, st = queryLedger({
                                        'args': '{"Args":["queryAlgos"]}'
                                    })
                                    if st != status.HTTP_200_OK:
                                        return Response(algoData, status=st)

                                    if algoData is None:
                                        algoData = []
                                for key, val in subfilters.items():
                                    filteredData = [x for x in algoData if x[key] in val]
                                    algoHashes = [x['key'] for x in filteredData]
                                    l[idx] = [x for x in l[idx] if x['traintuple']['algo']['hash'] in algoHashes]
                            elif k == 'dataset':  # select model which trainData.openerHash is
                                if not dataManagerData:
                                    # TODO find a way to put this call in cache
                                    dataManagerData, st = queryLedger({
                                        'args': '{"Args":["queryDataManagers"]}'
                                    })
                                    if st != status.HTTP_200_OK:
                                        return Response(dataManagerData, status=st)

                                    if dataManagerData is None:
                                        dataManagerData = []
                                for key, val in subfilters.items():
                                    filteredData = [x for x in dataManagerData if x[key] in val]
                                    datamanagerHashes = [x['key'] for x in filteredData]
                                    l[idx] = [x for x in l[idx] if x['traintuple']['dataset']['openerHash'] in datamanagerHashes]
                            elif k == 'objective':  # select objective used by these datamanagers
                                if not objectiveData:
                                    # TODO find a way to put this call in cache
                                    objectiveData, st = queryLedger({
                                        'args': '{"Args":["queryObjectives"]}'
                                    })
                                    if st != status.HTTP_200_OK:
                                        return Response(objectiveData, status=st)

                                    if objectiveData is None:
                                        objectiveData = []
                                for key, val in subfilters.items():
                                    if key == 'metrics':  # specific to nested metrics
                                        filteredData = [x for x in objectiveData if x[key]['name'] in val]
                                    else:
                                        filteredData = [x for x in objectiveData if x[key] in val]
                                    objectiveKeys = [x['key'] for x in filteredData]
                                    l[idx] = [x for x in l[idx] if x['traintuple']['objective']['hash'] in objectiveKeys]

        return Response(l, status=st)
Example #12
0
    def list(self, request, *args, **kwargs):
        # can modify result by interrogating `request.version`

        data, st = queryLedger({'args': '{"Args":["queryObjectives"]}'})

        data = [] if data is None else data
        objectives = [data]

        if st != status.HTTP_200_OK:
            return Response(objectives, status=st)

        dataManagerData = None
        algoData = None
        modelData = None

        # parse filters
        query_params = request.query_params.get('search', None)
        if query_params is None:
            return Response(objectives, status=st)

        try:
            filters = get_filters(query_params)
        except Exception:
            return Response(
                {'message': f'Malformed search filters {query_params}'},
                status=status.HTTP_400_BAD_REQUEST)

        # filtering
        objectives = []
        for idx, filter in enumerate(filters):
            # init each list iteration to data
            objectives.append(data)

            for k, subfilters in filter.items():
                if k == 'objective':  # filter by own key
                    for key, val in subfilters.items():
                        if key == 'metrics':  # specific to nested metrics
                            objectives[idx] = [
                                x for x in objectives[idx]
                                if x[key]['name'] in val
                            ]
                        else:
                            objectives[idx] = [
                                x for x in objectives[idx] if x[key] in val
                            ]

                elif k == 'dataset':  # select objective used by these datamanagers
                    if not dataManagerData:
                        # TODO find a way to put this call in cache
                        dataManagerData, st = queryLedger(
                            {'args': '{"Args":["queryDataManagers"]}'})
                        if st != status.HTTP_200_OK:
                            return Response(dataManagerData, status=st)
                        if dataManagerData is None:
                            dataManagerData = []

                    for key, val in subfilters.items():
                        filteredData = [
                            x for x in dataManagerData if x[key] in val
                        ]
                        dataManagerKeys = [x['key'] for x in filteredData]
                        objectiveKeys = [
                            x['objectiveKey'] for x in filteredData
                        ]
                        objectives[idx] = [
                            x for x in objectives[idx]
                            if x['key'] in objectiveKeys or (
                                x['testDataset'] and x['testDataset']
                                ['dataManagerKey'] in dataManagerKeys)
                        ]

                elif k == 'model':  # select objectives used by outModel hash
                    if not modelData:
                        # TODO find a way to put this call in cache
                        modelData, st = queryLedger(
                            {'args': '{"Args":["queryTraintuples"]}'})
                        if st != status.HTTP_200_OK:
                            return Response(modelData, status=st)
                        if modelData is None:
                            modelData = []

                    for key, val in subfilters.items():
                        filteredData = [
                            x for x in modelData if x['outModel'] is not None
                            and x['outModel'][key] in val
                        ]
                        objectiveKeys = [
                            x['objective']['hash'] for x in filteredData
                        ]
                        objectives[idx] = [
                            x for x in objectives[idx]
                            if x['key'] in objectiveKeys
                        ]

        return Response(objectives, status=st)
Example #13
0
    def list(self, request, *args, **kwargs):
        data, st = queryLedger({'args': '{"Args":["queryTraintuples"]}'})

        data = data if data else []

        return Response(data, status=st)