Ejemplo n.º 1
0
def main(req: func.HttpRequest) -> func.HttpResponse:
    logging.info('Python HTTP trigger function processed a request.')

    user_id = req.params.get('user_id')

    try:
        req_body = req.get_json()
        logging.info('req_body=%s', req_body)
    except Exception as e:
        logging.info(e)
    except ValueError as ve:
        logging.info(ve)

    asset_name = req_body.get('asset_name')

    if not user_id or not asset_name:
        return func.HttpResponse(
            "Please pass user_id on the query string or asset_name in the request body",
            status_code=400)

    ## Get User Info and check if user_id exists
    userdb = UserDB(config)
    try:
        user = userdb.get_user(user_id)
        if not user:
            logging.info(f"A user with user_id {user_id} not exists")
            return func.HttpResponse(
                f"A user with user_id {user_id} not exists", status_code=409)
    except Exception as e:
        logging.info(e)
        return func.HttpResponse(str(e), status_code=400)

    ## Create an asset for train for the person
    storage_info = AzureStorageBlockBlob.parse_storage_conn_string(
        config.get_value('AzureWebJobsStorage'))
    asset_id = AssetDB.gen_random_id()
    blobclient = AzureStorageBlockBlob(storage_info['AccountName'],
                                       storage_info['AccountKey'])
    try:
        blobclient.create_container(asset_id)
    except Exception as e:
        return func.HttpResponse(str(e), status_code=400)

    assetdb = AssetDB(config)
    try:
        assetdb.add_asset(asset_id, asset_name, user_id)
    except Exception as e:
        return func.HttpResponse(str(e), status_code=400)

    return func.HttpResponse(asset_id)
Ejemplo n.º 2
0
def main(req: func.HttpRequest) -> func.HttpResponse:

    try:
        req_body = req.get_json()
        logging.info('req_body=%s', req_body)
    except Exception as e:
        logging.info(e)
    except ValueError as ve:
        logging.info(ve)

    user_id = req_body.get('user_id')
    person_id = req_body.get('person_id')
    asset_id = req_body.get('asset_id')
    order = req_body.get('order')
    offset = req_body.get('offset')
    limit = req_body.get('limit')

    if not user_id:
        return func.HttpResponse("Please pass user_id in the request body",
                                 status_code=400)

    order_desc = True if order.lower == 'desc' else False
    offset = int(offset) if offset and int(offset) >= 0 else 0
    limit = int(limit) if limit and int(limit) >= 0 else 100

    storage_info = AzureStorageBlockBlob.parse_storage_conn_string(
        config.get_value('AzureWebJobsStorage'))
    photodb = PhotoDB(config)
    try:
        docs = photodb.get_photos(user_id=user_id,
                                  person_id=person_id,
                                  asset_id=asset_id,
                                  order_desc=order_desc,
                                  offset=offset,
                                  limit=limit)
        ret_doc = []
        for doc in list(docs):
            token_dict = AzureStorageBlockBlob.generate_sas_token(
                storage_info['AccountName'], storage_info['AccountKey'], "rl",
                1, doc['asset_id'], doc['blob_name'])
            doc['blob_url'] = token_dict['url']
            ret_doc.append(doc)
        return func.HttpResponse(json.dumps(docs))
    except Exception as e:
        return func.HttpResponse(str(e), status_code=400)
Ejemplo n.º 3
0
def main(req: func.HttpRequest) -> str:
    logging.info('Python HTTP trigger function processed a request.')

    # Get Azure Storage Connection String
    storage_account = None
    storage_key = None

    ll = connString.split(';')
    for l in ll:
        ss = l.split('=', 1)
        if len(ss) != 2:
            continue
        if ss[0] == 'AccountName':
            storage_account = ss[1]
        if ss[0] == 'AccountKey':
            storage_key = ss[1]
    if not storage_account or not storage_key:
        return write_http_response(
            400, {
                'message':
                'Function configuration error: NO Azure Storage connection string found!'
            })

    # Check HTTP Mehtod
    if req.method.lower() != _ALLOWED_HTTP_METHOD.lower():
        return write_http_response(
            405, {'message': 'Only POST HTTP Method is allowed'})

    permission = None
    container_name = None
    blob_name = None
    try:
        req_body = req.get_json()
    except ValueError:
        pass
    else:
        if not req_body.get('permission') or not req_body.get('container'):
            return write_http_response(
                400, {
                    'message':
                    'Permission and container parameters must be included in HTTP request body'
                })

    permission = req_body.get('permission')
    container_name = req_body.get('container')
    blob_name = req_body.get('blobname')
    token_ttl = _SAS_TOKEN_DEFAULT_TTL
    if req_body.get('ttl'):
        token_ttl = int(req_body.get('ttl'))
        if token_ttl < 1:
            return write_http_response(
                400, {'message': 'Token ttl must be digit and more than 0'})

    # Generate SAS Token
    token_dict = AzureStorageBlockBlob.generate_sas_token(
        storage_account, storage_key, permission, token_ttl, container_name,
        blob_name)
    logging.info("Generated Token token=>{} url=>{}".format(
        token_dict['token'], token_dict['url']))

    # Write HTTP Response
    return write_http_response(200, token_dict)
Ejemplo n.º 4
0
def main(req: func.HttpRequest) -> func.HttpResponse:
    logging.info('createperson function processed a request.')

    user_id = req.params.get('user_id')

    try:
        req_body = req.get_json()
        logging.info('req_body=%s', req_body)
    except Exception as e:
        logging.info(e)
    except ValueError as ve:
        logging.info(ve)

    person_name = req_body.get('person_name')

    if not user_id or not person_name:
        return func.HttpResponse(
            "Please pass both user_id and person_name on the query string or in the request body",
            status_code=400)

    ## Get User Info
    userdb = UserDB(config)
    user = None
    try:
        user = userdb.get_user(user_id)
        if not user:
            logging.info(f"A user with user_id {user_id} not exists")
            return func.HttpResponse(
                f"A user with user_id {user_id} not exists", status_code=409)
        if not 'person_group_id' in user:
            return func.HttpResponse(
                f"A user with user_id {user_id} does not have person_group_id",
                status_code=409)
    except Exception as e:
        logging.info(e)
        return func.HttpResponse(str(e), status_code=400)

    ## Create person
    storage_info = AzureStorageBlockBlob.parse_storage_conn_string(
        config.get_value('AzureWebJobsStorage'))
    faceapi = AzureCognitiveFaceAPI(config.get_value('FACEAPI_ENDPOINT'),
                                    config.get_value('FACEAPI_SUBKEY'),
                                    storage_info['AccountName'],
                                    storage_info['AccountKey'])

    created_person_id = None
    try:
        created_person = faceapi.create_person(user['person_group_id'],
                                               person_name)
        created_person_id = created_person.person_id
    except Exception as e:
        logging.info(e)
        return func.HttpResponse(str(e), status_code=400)

    ## Create an asset for train for the person
    asset_id = AssetDB.gen_random_id()
    blobclient = AzureStorageBlockBlob(storage_info['AccountName'],
                                       storage_info['AccountKey'])
    try:
        blobclient.create_container(asset_id)
    except Exception as e:
        return func.HttpResponse(str(e), status_code=400)

    ## Update user
    try:
        persons = user['persons'] if user['persons'] else []
        logging.info("persons=%s", persons)
        created_person = {
            "person_id": created_person_id,
            "person_name": person_name,
            "asset_id_for_train": asset_id
        }
        persons.append(created_person)
        user['persons'] = persons
        userdb.upsert_document(document=user)
        return func.HttpResponse(json.dumps(created_person))
    except Exception as e:
        return func.HttpResponse(str(e), status_code=400)
Ejemplo n.º 5
0
def main(event: func.EventGridEvent):
    result = json.dumps({
        'id': event.id,
        'data': event.get_json(),
        'topic': event.topic,
        'subject': event.subject,
        'event_type': event.event_type,
    })
    logging.info('Python EventGrid trigger processed an event: %s', result)

    # Event Validation
    if event.event_type != 'Microsoft.Storage.BlobCreated':
        logging.info('Invalid event_type: %s', event.event_type)
        return  # Skip

    # Get Blockblob url
    event_data = event.get_json()
    blob_url = event_data['url']
    logging.info('Blob url: %s', blob_url)

    # Get Blob Container and file name
    container_name, file_name = AzureStorageBlockBlob.parse_url(blob_url)
    logging.info('Blob container=%s file=%s', container_name, file_name)

    ## 1. Get user_id from container_name: CosmosDB
    assetdb = AssetDB(config)
    user_id = assetdb.get_user_id(container_name)
    logging.info('user_id: %s', user_id)

    ## 2. Get userinfo from CosmosDB using user_id: CosmosDB
    userdb = UserDB(config)
    user = userdb.get_user(user_id)
    group_id = user['person_group_id']
    person_ids = []
    for p in user['persons']:
        person_ids.append(p['person_id'])
    logging.info('group_id: %s person_ids: %s', group_id, ','.join(person_ids))

    ## 3. Identify faces
    storage_info = AzureStorageBlockBlob.parse_storage_conn_string(
        config.get_value('AzureWebJobsStorage'))
    faceapi = AzureCognitiveFaceAPI(config.get_value('FACEAPI_ENDPOINT'),
                                    config.get_value('FACEAPI_SUBKEY'),
                                    storage_info['AccountName'],
                                    storage_info['AccountKey'])
    ret_dict = faceapi.identify_face_blob(group_id,
                                          container_name=container_name,
                                          blob_name=file_name,
                                          max_num_of_candidates_returned=1,
                                          confidence_threshold=0.5)
    person_included = False
    identified_persons = []
    for r in ret_dict:
        logging.info("detected_person_id: %s person_face_id: %s",
                     r['person_id'], r['face_id'])
        identified_persons.append({"person_id": r['person_id']})

    ## 4. Regist face tags: CosmosDB
    photodb = PhotoDB(config)
    photo_id = PhotoDB.gen_id(container_name, file_name)
    logging.info("photo_id = {}".format(photo_id))
    added_photo = photodb.add_photo(container_name, file_name, user_id,
                                    identified_persons)
    logging.info("added_photo: %s", added_photo)
Ejemplo n.º 6
0
def main(msg: func.QueueMessage) -> None:
    received_message = msg.get_body().decode('utf-8')
    o = json.loads(received_message)
    if not 'user_id' in o or not 'person_id' in o:
        logging.error(
            "Invalid message: message needs to contain both user_id and person_id"
        )
        return
    user_id = o['user_id']
    person_id = o['person_id']
    logging.info("train user_id=%s person_id=%s", user_id, person_id)

    ## Get User Info
    userdb = UserDB(config)
    user = None
    try:
        user = userdb.get_user(user_id)
        if not user:
            logging.info(f"A user with user_id {user_id} not exists")
            return func.HttpResponse(
                f"A user with user_id {user_id} not exists", status_code=409)
    except Exception as e:
        logging.info(e)
        return func.HttpResponse(str(e), status_code=400)
    person_group_id = user['person_group_id']

    ## Get asset_id for person_id
    asset_id_for_train = None
    persons = user['persons']
    for person in persons:
        if person_id == person['person_id']:
            asset_id_for_train = person['asset_id_for_train']
            break
    if not asset_id_for_train:
        logging.error(
            "Invalid user info: persons in user info do not contain asset_id_for_train for person_id {} of user_id {}"
            .format(person_id, user_id))
        return

    ## Glob blobs and add faces to person_id
    storage_info = AzureStorageBlockBlob.parse_storage_conn_string(
        config.get_value('AzureWebJobsStorage'))
    blobclient = AzureStorageBlockBlob(storage_info['AccountName'],
                                       storage_info['AccountKey'])
    photo_files = []
    try:
        photo_files = blobclient.list_blob(asset_id_for_train)
    except Exception as e:
        logging.error("Error: user_id {} person_id {}: {}".format(
            user_id, person_id, str(e)))
        return

    faceapi = AzureCognitiveFaceAPI(config.get_value('FACEAPI_ENDPOINT'),
                                    config.get_value('FACEAPI_SUBKEY'),
                                    storage_info['AccountName'],
                                    storage_info['AccountKey'])
    for photo_file in photo_files:
        try:
            faceapi.add_face_blob(person_group_id, person_id,
                                  asset_id_for_train, photo_file)
        except Exception as e:
            logging.error(
                "Error: user_id {} person_id {} asset_id {} photo_file {}: {}".
                format(user_id, person_id, asset_id_for_train, photo_file,
                       str(e)))
            return

    ## Train PersonGroup
    try:
        faceapi.train_person_group(person_group_id)
    except Exception as e:
        logging.error("Error: user_id {} person_id {} asset_id {}: {}".format(
            user_id, person_id, asset_id_for_train, str(e)))
        return

    logging.info(
        "Train succeeded!: user_id {} person_id {} asset_id {}".format(
            user_id, person_id, asset_id_for_train))
Ejemplo n.º 7
0
 def __init__(self, faceapi_endpoint, faceapi_subkey, storage_account_name,
              storage_account_key):
     self._face_client = FaceClient(
         faceapi_endpoint, CognitiveServicesCredentials(faceapi_subkey))
     self._blob_client = AzureStorageBlockBlob(storage_account_name,
                                               storage_account_key)
Ejemplo n.º 8
0
class AzureCognitiveFaceAPI(object):
    def __init__(self, faceapi_endpoint, faceapi_subkey, storage_account_name,
                 storage_account_key):
        self._face_client = FaceClient(
            faceapi_endpoint, CognitiveServicesCredentials(faceapi_subkey))
        self._blob_client = AzureStorageBlockBlob(storage_account_name,
                                                  storage_account_key)

    def create_person_group(self, group_id, group_name):
        # SDK ref: https://t.ly/PbDGr
        return self._face_client.person_group.create(person_group_id=group_id,
                                                     name=group_name)

    def train_person_group(self, group_id):
        # SDK ref: https://t.ly/xYkmw
        # Train the person group
        self._face_client.person_group.train(group_id)
        while (True):
            training_status = self._face_client.person_group.get_training_status(
                group_id)
            logging.info("Training status: {}.".format(training_status.status))
            if (training_status.status is TrainingStatusType.succeeded):
                break
            elif (training_status.status is TrainingStatusType.failed):
                raise Exception("Training the person group has failed")
            time.sleep(5)

    def create_person(self, group_id, person_name):
        # {'additional_properties': {}, 'name': None, 'user_data': None, 'person_id': '683507d1-5c55-4f59-a389-68f8707589ad', 'persisted_face_ids': None}
        # SDK ref:  https://t.ly/K19Bb
        return self._face_client.person_group_person.create(
            group_id, person_name)

    def delete_person(self, group_id, person_id):
        # SDK ref:  https://t.ly/7rb5X
        return self._face_client.person_group_person.delete(
            group_id, person_id)

    def add_face_stream(self, group_id, person_id, stream):
        # {'additional_properties': {}, 'persisted_face_id': '4a8313db-6eb8-4a89-b058-23073c04571c', 'user_data': None}
        # SDK ref: https://t.ly/9gnel
        return self._face_client.person_group_person.add_face_from_stream(
            group_id, person_id, stream)

    def add_face_blob(self, group_id, person_id, container_name, blob_name):
        in_stream = io.BytesIO()
        self._blob_client.get_blob_stream(container_name, blob_name, in_stream)
        in_stream.seek(0)
        return self.add_face_stream(group_id, person_id, in_stream)

    def identify_face_stream(self,
                             group_id,
                             stream,
                             max_num_of_candidates_returned=1,
                             confidence_threshold=None):
        # Detect faces
        # SDK ref: https://t.ly/K19RP
        face_ids = []
        faces = self._face_client.face.detect_with_stream(stream)
        for face in faces:
            face_ids.append(face.face_id)
        # Identify faces
        # SDK ref: https://t.ly/0vrV5
        # confidence_threshold: 0-1
        results = self._face_client.face.identify(
            face_ids,
            group_id,
            max_num_of_candidates_returned=max_num_of_candidates_returned,
            confidence_threshold=confidence_threshold)
        ret = []
        if not results:
            print('No person identified in the person group for faces')
            return ret

        for face in results:
            if len(face.candidates) > 0:
                person_id = face.candidates[0].person_id
                confidence = face.candidates[0].confidence
                # print('face_id: {}, person_id: {}, confidence: {}.'.format(face.face_id, person_id, confidence))
                ret.append({
                    "face_id": face.face_id,
                    "person_id": person_id,
                    "confidence": confidence
                })
        return ret

    def identify_face_blob(self,
                           group_id,
                           container_name,
                           blob_name,
                           max_num_of_candidates_returned=1,
                           confidence_threshold=None):
        in_stream = io.BytesIO()
        self._blob_client.get_blob_stream(container_name, blob_name, in_stream)
        in_stream.seek(0)
        return self.identify_face_stream(group_id, in_stream,
                                         max_num_of_candidates_returned,
                                         confidence_threshold)
Ejemplo n.º 9
0
def main(req: func.HttpRequest) -> func.HttpResponse:
  logging.info('Python HTTP trigger function processed a request.')

  try:
    req_body = req.get_json()
    logging.info('req_body=%s',req_body)
  except Exception as e:
    logging.info(e)
  except ValueError as ve:
    logging.info(ve)

  user_id = req_body.get('user_id')
  user_name = req_body.get('user_name') if req_body.get('user_name') else user_id

  if not user_id:
    # return func.HttpResponse(f"Hello {name}!")
    return func.HttpResponse(
        "Please pass a name on the query string or in the request body",
        status_code=400
    )

  ## Get user and check if it's already registed
  userdb = UserDB(config)
  try:
    user = userdb.get_user(user_id)
    if user:
      logging.info(f"A user with user_id {user_id} already exists")
      return func.HttpResponse(
          f"A user with user_id {user_id} already exists",
          status_code=409
      )
  except Exception as e:
    logging.info(e)
    return func.HttpResponse(
        str(e),
        status_code=400
    )

  ## Create person_group_id
  storage_info = AzureStorageBlockBlob.parse_storage_conn_string(config.get_value('AzureWebJobsStorage'))
  faceapi = AzureCognitiveFaceAPI(
        config.get_value('FACEAPI_ENDPOINT'),
        config.get_value('FACEAPI_SUBKEY'),
        storage_info['AccountName'], 
        storage_info['AccountKey'] )

  person_group_id = user_id
  person_group_name = user_name
  try:
    faceapi.create_person_group(person_group_id, person_group_name)
  except Exception as e:
    logging.info(e)
    return func.HttpResponse(
        str(e), 
        status_code=400
    )

  ## Regist user
  userdb = UserDB(config)
  try:
    userdb.add_user(user_id, user_name, person_group_id)
  except Exception as e:
    return func.HttpResponse(
        str(e),
        status_code=400
    )

  # return func.HttpResponse(f"Hello {user_id}!")
  return func.HttpResponse(user_id)