def verbose_report(encoding: Encoding): """ Verbose mode reporting of media id and its contents by dispatching a GetStatus action and organizing the report contents into mediaid buckets :return: """ print('Verbose mode enabled, GetStatus for each of the mediaid reported:') pretty = PrettyPrinter() status, response = encoding.get_media_list() response = get_response(response) for media in response['media']: try: output = {} output[media['mediaid']] = media pretty.pprint(output) status, status_reponse = encoding.get_status(mediaid=media['mediaid']) print('Status for mediaid: %s' % media['mediaid']) pretty.pprint(status_reponse) status, media_info_response = encoding.get_media_info(extended=True, mediaid=media['mediaid']) print('MediaInfo (extended) for mediaid: %s' % media['mediaid']) pretty.pprint(media_info_response) print('\n') except EncodingErrors as ex: print('*** Encoding Error Found!: %s' % str(ex))
def verbose_report(encoding: Encoding): """ Verbose mode reporting of media id and its contents by dispatching a GetStatus action and organizing the report contents into mediaid buckets :return: """ print('Verbose mode enabled, GetStatus for each of the mediaid reported:') pretty = PrettyPrinter() status, response = encoding.get_media_list() response = get_response(response) for media in response['media']: try: output = {} output[media['mediaid']] = media pretty.pprint(output) status, status_reponse = encoding.get_status( mediaid=media['mediaid']) print('Status for mediaid: %s' % media['mediaid']) pretty.pprint(status_reponse) status, media_info_response = encoding.get_media_info( extended=True, mediaid=media['mediaid']) print('MediaInfo (extended) for mediaid: %s' % media['mediaid']) pretty.pprint(media_info_response) print('\n') except EncodingErrors as ex: print('*** Encoding Error Found!: %s' % str(ex))
def setUp(self): """ Setup a encoding.com object :return: """ user_id = getenv('ENCODING_USER_ID') user_key = getenv('ENCODING_USER_KEY') self.encoding = Encoding(user_id, user_key)
def setUp(self): """ Setup a encoding.com object :return: """ self.logger = getLogger() user_id = getenv('ENCODING_USER_ID') user_key = getenv('ENCODING_USER_KEY') self.encoding = Encoding(user_id, user_key) self.source = getenv('ENCODING_TEST_SOURCE') # Does not accept local file paths - Use http(s)://<PATH TO FILE> or FTP url
def main(args: Namespace): """ Main entry point used as a stand alone python execution :param args: Namespace arguments from the arguments parser :return: """ args_dict = vars(args) encoding = Encoding(user_id=args_dict['user'], user_key=args_dict['key']) if args_dict['mediaid']: media_id = args_dict['mediaid'] else: media_id = get_latest_media(encoding)['mediaid'] print( 'MediaId not specified, using the latest media id in the queue: %s' % media_id) Poller.poll_status(encoding, media_id=media_id, callback=pretty_print_response, interval=float(args_dict['interval']))
def main(args: Namespace): """ Main entry point used as a stand alone python execution :param args: Namespace arguments from the arguments parser :return: """ args_dict = vars(args) encoding = Encoding(user_id=args_dict['user'], user_key=args_dict['key']) if args_dict['mediaid']: media_id = args_dict['mediaid'] else: media_id = get_latest_media(encoding)['mediaid'] print('MediaId not specified, cancelling the media id in the queue: %s' % media_id) encoding.cancel_media(mediaid=[media_id])
def main(args: Namespace): """ Main entry point used as a stand alone python execution :param args: Namespace arguments from the arguments parser :return: """ args_dict = vars(args) encoding = Encoding(user_id=args_dict['user'], user_key=args_dict['key']) if args_dict['verbose']: verbose_report(encoding) else: status, response = encoding.get_media_list() if 200 == status: pretty_print_response(get_response(response)) else: print('HTTP error returned: %s' % status)
def get_latest_media(service: Encoding) -> dict: """ Get latest media id information :param service: Encoding Encoding service class :return: dictionary response from the encoding.com :rtype: dict """ status, response = service.get_media_list() response = get_response(response) medias = response['media'] return medias[len(medias) - 1]
class EncodingNegative(TestCase): """ Coverage for encoding.com positive tests """ def setUp(self): """ Setup a encoding.com object :return: """ user_id = getenv('ENCODING_USER_ID') user_key = getenv('ENCODING_USER_KEY') self.encoding = Encoding(user_id, user_key) def tearDown(self): pass def test_get_media_info(self): """ Negative test for GetMediaInfo: * Missing media id from client * Invalid media id not found :return: """ with self.assertRaises(EncodingErrors): self.encoding.get_media_info(False, mediaid=[]) self.encoding.get_media_info(False, mediaid=['1', '2']) def test_get_status(self): """ Negative test for GetStatus: * invalid mediaid using both python list and native encoding.com expected :return: """ with self.assertRaises(EncodingErrors): self.encoding.get_status(mediaid=[]) def test_add_media(self): """ :return: """ mp4_libx264 = {'output': 'mp4', 'video_codec': 'libx264'} with self.assertRaises(EncodingErrors): self.encoding.add_media(source=[], format=mp4_libx264)
def poll_till_status(service: Encoding, media_id: str, callback=None, status='Finished', interval: float=5): """ Continuously update the status of the given media_id until desired state. Call the given callback to handle the completion state Note: Written to support a non-notification url workflow only. We should support notification URL as this will generate a lot of noise. Any sleep states to encoding.com may miss states that complete very fast and will NOT be caught by polling. "finished" or "error" state is one that is always reflects completion :param service: Encoding service class to Encoding :param media_id: str Desired media_id to poll status for :param callback: Client callback to invoke once encountering desired status (optional) If no callback specified, this will poll until desired status or until exit condition is satisfied Error and Finished status also triggers this call as this marks the end of the job and status not encountered during polling :param status: str desired state for callback. Should the status not be found, callback will be invoked for either "finished" or "error" :param interval: float Interval between each polling operation :return: last state reflected by GetStatus action :rtype: dict """ if status not in Encoding.EXIT_STATUSES: exit_statuses = set(Encoding.EXIT_STATUSES) exit_statuses.add(status) else: exit_statuses = Encoding.EXIT_STATUSES while True: http_status, response = service.get_status(mediaid=media_id) response = get_response(response) status = response['status'] if status in exit_statuses: if callback: callback(media_id=media_id, status=status, response=response) return response sleep(interval)
def poll_status(service: Encoding, media_id: str, callback=None, status='Finished', interval: float=5): """ Continuously poll for status changes from the prior state. :param service: Encoding service class to Encoding :param media_id: str Desired media_id to poll status for :param callback: Client callback to invoke per state change encountered If no callback specified, this will poll until desired status or until exit condition is satisfied Error and Finished status also triggers this call as this marks the end of the job and status not encountered during polling :param status: :param interval: float Interval to poll at... some of these states goes by very quickly depending on the encoding.com bandwidth Set to spammy 0 if you want to track all the changes :return: None """ if status not in Encoding.EXIT_STATUSES: exit_statuses = set(Encoding.EXIT_STATUSES) exit_statuses.add(status) else: exit_statuses = Encoding.EXIT_STATUSES last_status = '' while True: http_status, response = service.get_status(mediaid=media_id) response = get_response(response) status = response['status'] if status != last_status: last_status = status if callback: callback(media_id=media_id, status=status, response=response) if status in exit_statuses: return response sleep(interval)
if status in exit_statuses: return response sleep(interval) @staticmethod def print_response(**kwargs): """ Simply print the response from encoding.com :param :return: None """ print('MediaID {0} response for status {1}:\n{2}'.format( kwargs['media_id'], kwargs['status'], str(kwargs['response']))) if __name__ == '__main__': encoding = Encoding(getenv('ENCODING_USER_ID'), getenv('ENCODING_USER_KEY')) media = get_latest_media(encoding) # track each state polling Poller.poll_status(encoding, media_id=media['mediaid'], callback=Poller.print_response, interval=0) # poll till status variant Poller.poll_till_status(encoding, media_id=media['mediaid'], callback=Poller.print_response) # response = Poller.poll_till_status(encoding, media_id=media['mediaid'])
class EncodingPositive(TestCase): """ Coverage for encoding.com positive tests """ def setUp(self): """ Setup a encoding.com object :return: """ self.logger = getLogger() user_id = getenv('ENCODING_USER_ID') user_key = getenv('ENCODING_USER_KEY') self.encoding = Encoding(user_id, user_key) self.source = getenv('ENCODING_TEST_SOURCE') # Does not accept local file paths - Use http(s)://<PATH TO FILE> or FTP url def tearDown(self): pass def test_media_apis(self): """ Positive test for medias already uploaded in encoding.com by using the 1st found media as a baseline for all API calls * get_media_list * get_status * get_media_info :return: """ try: status, response = self.encoding.get_media_list() response = get_response(response) medias = response['media'] first_media = medias[0] media_id = first_media.get('mediaid') if media_id: self.encoding.get_status(mediaid=media_id) self.encoding.get_media_info(False, mediaid=media_id) self.encoding.get_media_info(True, mediaid=media_id) except KeyError: # possible that there are no media currently found in the encoding.com pass except EncodingErrors: # Encoding Errors are possible as a job may be in a wierd state (ie. not downloaded) # thus resulting in an error from encoding.com pass except: self.fail('Unexpected exception happened, should not happen') def test_get_status(self): """ Positive test for get_status. 1. Single status 2. Extended variant of the call to get multiple status(s) :return: """ try: status, response = self.encoding.get_media_list() response = get_response(response) medias = response['media'] # single media id variant status, result = self.encoding.get_status(mediaid=medias[0].get('mediaid')) self.logger.info('Multiple GetStatus (single variant) results:') self.logger.info(result) # multiple media id (extended variant of the call) media_ids = [] for media in medias: media_ids.append(media.get('mediaid')) status, result = self.encoding.get_status(mediaid=media_ids) self.logger.info('Multiple GetStatus (extended variant) results:') self.logger.info(result) except KeyError: # possible that there are no media currently found in the encoding.com pass except EncodingErrors: # GetStatus should always function, unlike GetMediaInfo... # haven't found a condition where GetStatus fails with an error self.fail('Encoding Error happened and should not have') except: self.fail('General exception should not have happened') def test_add_media(self): """ Positive test for get_media :return: """ try: destination_format = {'output': 'mp4', 'video_codec': 'libx264'} status, result = self.encoding.add_media(source=self.source, format=destination_format, destination=[]) self.logger.info('Add Media results:') self.logger.info(result) except KeyError: # possible that there are no media currently found in the encoding.com pass except EncodingErrors: # AddMedia should always function, unlike GetMediaInfo... self.fail('Encoding Error happened and should not have') except: self.fail('General exception should not have happened') def test_add_media_benchmark(self): """ Positive test for get_media_benchmark. :return: """ try: destination_format = {'output': 'mp4', 'video_codec': 'libx264'} status, result = self.encoding.add_media_benchmark(source=self.source, format=destination_format, destination=[]) self.benchmark_result_mediaid = result['response']['MediaID'] self.logger.info('Add Media Benchmark results:') self.logger.info(result) except KeyError: # possible that there are no media currently found in the encoding.com pass except EncodingErrors: # AddMedia should always function, unlike GetMediaInfo... self.fail('Encoding Error happened and should not have') except: self.fail('General exception should not have happened') def test_process_media(self): """ Positive test for process_media :return: """ status, response = self.encoding.get_media_list() response = get_response(response) media = response['media'] media_id = None for item in media: file_url = item['mediafile'] filename = self.get_filename_from_url(file_url) test_filename = self.get_filename_from_url(self.source) if filename == test_filename and 'Ready to process' in item['mediastatus']: media_id = item['mediaid'] break if media_id: try: status, result = self.encoding.process_media(mediaid=media_id, format={'output': 'mp4', 'video_codec': 'libx264'}) if not result['response']['message'] == 'Started': self.fail('Media was not started') except KeyError: self.fail('Did not return expected response') def test_get_media_list(self): """ Positive test for get_media_list :return: """ status, result = self.encoding.get_media_list() def get_filename_from_url(self, file_url): file_url_components = file_url.split('/') filename = file_url_components[len(file_url_components)-1] return filename