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)
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)
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)
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)
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)
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))
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)
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)
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)