diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..0097e9f --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,2 @@ +[tool.black] +skip-string-normalization = true diff --git a/qencode3/__init__.py b/qencode3/__init__.py index c9e82af..575f333 100644 --- a/qencode3/__init__.py +++ b/qencode3/__init__.py @@ -1,41 +1,50 @@ - def client(api_key, api_url=None, version=None, **kwargs): - from . client import Client + from .client import Client + return Client(api_key, api_url=api_url, version=version, **kwargs) + def custom_params(): - from . custom_params import CustomTranscodingParams - return CustomTranscodingParams() + from .custom_params import CustomTranscodingParams + + return CustomTranscodingParams() + def format(): - from . custom_params import Format - return Format() + from .custom_params import Format + + return Format() + def destination(): - from . custom_params import Destination - return Destination() + from .custom_params import Destination + + return Destination() + def stream(): - from . custom_params import Stream - return Stream() + from .custom_params import Stream + + return Stream() + def x264_video_codec(): - from . custom_params import Libx264_VideoCodecParameters - return Libx264_VideoCodecParameters() + from .custom_params import Libx264_VideoCodecParameters + + return Libx264_VideoCodecParameters() + def x265_video_codec(): - from . custom_params import Libx265_VideoCodecParameters - return Libx265_VideoCodecParameters() + from .custom_params import Libx265_VideoCodecParameters -from . exeptions import QencodeClientException, QencodeTaskException + return Libx265_VideoCodecParameters() -from . tools import generate_aws_signed_url +from .exeptions import QencodeClientException, QencodeTaskException + +from .tools import generate_aws_signed_url __version__ = "0.9.30" __status__ = "Beta" __author__ = "Qencode" - - - diff --git a/qencode3/client.py b/qencode3/client.py index 1f519ef..e018698 100644 --- a/qencode3/client.py +++ b/qencode3/client.py @@ -1,49 +1,51 @@ -from . httptools import Http -from . task import Task -from . metadata import Metadata +from .httptools import Http +from .task import Task +from .metadata import Metadata + class Client(object): - """ + """ :return: encoder object """ - def __init__(self, api_key, api_url=None, version=None): - self.api_key = api_key - self.api_url = api_url if api_url else 'https://api.qencode.com/' - self.version = version if version else 'v1' - self.connect = Http(self.version, self.api_url) - self.access_token = None - self.expire = None - self.error = None - self.code = None - self.message = '' - self._get_access_token() - - def create_task(self, **kwargs): - return Task(self.access_token, self.connect, **kwargs) - - def refresh_access_token(self, **kwargs): - response = self.connect.request('access_token', dict(api_key=self.api_key)) - if not response['error']: - self.access_token = response['token'] - self.expire = response['expire'] - else: - self.error = response['error'] - self.code = response['error'] - self.message = response.get('message') - - def _get_access_token(self): - response = self.connect.request('access_token', dict(api_key=self.api_key)) - if not response['error']: - self.access_token = response['token'] - self.expire = response['expire'] - else: - self.error = response['error'] - self.code = response['error'] - self.message = response.get('message') - - def get_metadata(self, uri): - metadata = Metadata(self.access_token, self.connect) - video_info = metadata.get(uri) - return video_info + + def __init__(self, api_key, api_url=None, version=None): + self.api_key = api_key + self.api_url = api_url if api_url else 'https://api.qencode.com/' + self.version = version if version else 'v1' + self.connect = Http(self.version, self.api_url) + self.access_token = None + self.expire = None + self.error = None + self.code = None + self.message = '' + self._get_access_token() + + def create_task(self, **kwargs): + return Task(self.access_token, self.connect, **kwargs) + + def refresh_access_token(self, **kwargs): + response = self.connect.request('access_token', dict(api_key=self.api_key)) + if not response['error']: + self.access_token = response['token'] + self.expire = response['expire'] + else: + self.error = response['error'] + self.code = response['error'] + self.message = response.get('message') + + def _get_access_token(self): + response = self.connect.request('access_token', dict(api_key=self.api_key)) + if not response['error']: + self.access_token = response['token'] + self.expire = response['expire'] + else: + self.error = response['error'] + self.code = response['error'] + self.message = response.get('message') + + def get_metadata(self, uri): + metadata = Metadata(self.access_token, self.connect) + video_info = metadata.get(uri) + return video_info diff --git a/qencode3/const.py b/qencode3/const.py index f9c0e9a..4acc0c3 100644 --- a/qencode3/const.py +++ b/qencode3/const.py @@ -3,18 +3,18 @@ SLEEP_ERROR = 60 COMPLETED_STATUS = ['completed', 'saved'] -ERROR_OK = 0 -ERROR_SERVER_INTERNAL = 1 -ERROR_BAD_APP_ID = 2 -ERROR_APP_ID_NOT_FOUND = 3 -ERROR_BAD_TOKEN = 4 -ERROR_TOKEN_NOT_FOUND = 5 -ERROR_TARIFF_NOT_PAID = 6 -ERROR_MASTER_NOT_FOUND = 7 -ERROR_SYSTEM_BUSY = 8 -ERROR_BAD_PAYLOAD = 9 +ERROR_OK = 0 +ERROR_SERVER_INTERNAL = 1 +ERROR_BAD_APP_ID = 2 +ERROR_APP_ID_NOT_FOUND = 3 +ERROR_BAD_TOKEN = 4 +ERROR_TOKEN_NOT_FOUND = 5 +ERROR_TARIFF_NOT_PAID = 6 +ERROR_MASTER_NOT_FOUND = 7 +ERROR_SYSTEM_BUSY = 8 +ERROR_BAD_PAYLOAD = 9 ERROR_PROJECT_NOT_FOUND = 10 -ERROR_BAD_PROFILE = 11 +ERROR_BAD_PROFILE = 11 ERROR_PROFILE_NOT_FOUND = 12 -ERROR_BAD_TOKENS = 13 -ERROR_FIELD_REQUIRED = 14 \ No newline at end of file +ERROR_BAD_TOKENS = 13 +ERROR_FIELD_REQUIRED = 14 diff --git a/qencode3/custom_params.py b/qencode3/custom_params.py index 3b280c1..6f5c3c6 100644 --- a/qencode3/custom_params.py +++ b/qencode3/custom_params.py @@ -1,148 +1,152 @@ import json from json import JSONEncoder -from . utils import rm_attributes_if_null +from .utils import rm_attributes_if_null + class CustomTranscodingParams(object): - """CustomTranscodingParams + """CustomTranscodingParams :var source: String. Source video URI. Can be http(s) url or tus uri :var format: String. A list of objects, each describing params for a single output video stream (MP4, WEBM, HLS or MPEG-DASH) """ - def __init__(self): - self.source = None - self.format = None - self.callback_url = None - rm_attributes_if_null(self) - def remove_null_params(self): - rm_attributes_if_null(self) + def __init__(self): + self.source = None + self.format = None + self.callback_url = None + rm_attributes_if_null(self) + + def remove_null_params(self): + rm_attributes_if_null(self) + class Format(object): - """ + """ :var :var """ - def __init__(self): - self.output = None - self.file_extension = None - self.destination = None - self.segment_duration = None - self.stream = None - self.logo = None - self.start_time = None - self.duration = None - self.is_watermark = None - self.size = None - self.video_codec = None - self.audio_codec = None - self.aspect_ratio = None - self.quality = None - self.interval = None - self.width = None - self.height = None - self.time = None - self.path = None - self.resize_mod = None - rm_attributes_if_null(self) - - def remove_null_params(self): - rm_attributes_if_null(self) + + def __init__(self): + self.output = None + self.file_extension = None + self.destination = None + self.segment_duration = None + self.stream = None + self.logo = None + self.start_time = None + self.duration = None + self.is_watermark = None + self.size = None + self.video_codec = None + self.audio_codec = None + self.aspect_ratio = None + self.quality = None + self.interval = None + self.width = None + self.height = None + self.time = None + self.path = None + self.resize_mod = None + rm_attributes_if_null(self) + + def remove_null_params(self): + rm_attributes_if_null(self) + class Destination(object): - def __init__(self): - self.url = None - self.key = None - self.secret = None - self.permissions = None - self.storage_class = None - rm_attributes_if_null(self) + def __init__(self): + self.url = None + self.key = None + self.secret = None + self.permissions = None + self.storage_class = None + rm_attributes_if_null(self) - def remove_null_params(self): - rm_attributes_if_null(self) + def remove_null_params(self): + rm_attributes_if_null(self) -class Stream(object): - def __init__(self): - self.size = None - self.video_codec = None - self.bitrate = None - self.quality = None - self.rotate = None - self.framerate = None - self.pix_format = None - self.profile = None - self.video_codec_parameters = None - self.keyframe = None - self.segment_duration = None - self.start_time = None - self.duration = None - self.audio_bitrate = None - self.audio_sample_rate = None - self.audio_channels_number = None - self.audio_codec = None - self.downmix_mode = None - self.logo = None - self.aspect_ratio = None - rm_attributes_if_null(self) - - def remove_null_params(self): - rm_attributes_if_null(self) +class Stream(object): + def __init__(self): + self.size = None + self.video_codec = None + self.bitrate = None + self.quality = None + self.rotate = None + self.framerate = None + self.pix_format = None + self.profile = None + self.video_codec_parameters = None + self.keyframe = None + self.segment_duration = None + self.start_time = None + self.duration = None + self.audio_bitrate = None + self.audio_sample_rate = None + self.audio_channels_number = None + self.audio_codec = None + self.downmix_mode = None + self.logo = None + self.aspect_ratio = None + rm_attributes_if_null(self) + + def remove_null_params(self): + rm_attributes_if_null(self) class Libx264_VideoCodecParameters(object): - def __init__(self): - self.vprofile = None - self.level = None - self.coder = None - self.flags2 = None - self.partitions = None - self.bf = None - self.directpred = None - self.me_method = None - rm_attributes_if_null(self) - - def remove_null_params(self): - rm_attributes_if_null(self) + def __init__(self): + self.vprofile = None + self.level = None + self.coder = None + self.flags2 = None + self.partitions = None + self.bf = None + self.directpred = None + self.me_method = None + rm_attributes_if_null(self) + + def remove_null_params(self): + rm_attributes_if_null(self) + class Libx265_VideoCodecParameters(object): - def __init__(self): - pass + def __init__(self): + pass class MyEncoder(JSONEncoder): - def default(self, obj): - return obj.__dict__ + def default(self, obj): + return obj.__dict__ class Query(object): - def __init__(self): - self.params = None - self.error = None - self.message = '' - self.query = None - - def prepare_params(self): - query = dict(query=self.params) - try: - self.query = json.dumps(query, cls=MyEncoder) - except BaseException as e: - self.error = True - self.message = repr(e) - - def validate_params(self): - if not self.params: - self.error = True - self.message = 'Params is required' - return - if not 'source' in self.params.__dict__: - self.error = True - self.message = 'Params: source is required' - return - if not 'format' in self.params.__dict__: - self.error = True - self.message = 'Params: format is required' - return - - + def __init__(self): + self.params = None + self.error = None + self.message = '' + self.query = None + + def prepare_params(self): + query = dict(query=self.params) + try: + self.query = json.dumps(query, cls=MyEncoder) + except BaseException as e: + self.error = True + self.message = repr(e) + + def validate_params(self): + if not self.params: + self.error = True + self.message = 'Params is required' + return + if not 'source' in self.params.__dict__: + self.error = True + self.message = 'Params: source is required' + return + if not 'format' in self.params.__dict__: + self.error = True + self.message = 'Params: format is required' + return diff --git a/qencode3/exeptions.py b/qencode3/exeptions.py index b904f9c..fa5b795 100644 --- a/qencode3/exeptions.py +++ b/qencode3/exeptions.py @@ -1,14 +1,15 @@ class QencodeException(Exception): - def __init__(self, message, *args): - super(QencodeException, self).__init__(message, *args) - self.error = message - self.arg = [i for i in args] + def __init__(self, message, *args): + super(QencodeException, self).__init__(message, *args) + self.error = message + self.arg = [i for i in args] + class QencodeClientException(QencodeException): - def __init__(self, message, *args): - super(QencodeClientException, self).__init__(message, *args) + def __init__(self, message, *args): + super(QencodeClientException, self).__init__(message, *args) class QencodeTaskException(QencodeException): - def __init__(self, message, *args): - super(QencodeTaskException, self).__init__(message, *args) \ No newline at end of file + def __init__(self, message, *args): + super(QencodeTaskException, self).__init__(message, *args) diff --git a/qencode3/httptools.py b/qencode3/httptools.py index b933b6b..6b38cdc 100644 --- a/qencode3/httptools.py +++ b/qencode3/httptools.py @@ -1,52 +1,57 @@ import json + # import urllib import urllib.request as urllib2 from urllib.parse import urljoin from urllib.parse import urlencode + class Http(object): - def __init__(self, version, url, debug=False): - self.version = version - self.url = url - self._debug = debug + def __init__(self, version, url, debug=False): + self.version = version + self.url = url + self._debug = debug - def _call_server(self, url, post_data): - if not url: - response = dict(error=True, message='AttributeError: Bad URL: ' + str(url)) - return json.dumps(response) - data = urlencode(post_data).encode("utf-8") - request = urllib2.Request(url, data) - #print('call_server: ', url, data) - try: - res = urllib2.urlopen(request) - except urllib2.HTTPError as e: - headers = e.headers if self._debug else '' - response = dict(error=True, message='HTTPError: {0} {1} {2}'.format(e.code, e.reason, headers)) - response = json.dumps(response) - except urllib2.URLError as e: - response = dict(error=True, message='URLError: {0}'.format(e.reason)) - response = json.dumps(response) - except BaseException as e: - response = dict(error=True, message='Error: {0}'.format(e)) - response = json.dumps(response) - else: - res2 = res.read() - response = res2 if isinstance(res2, str) else res2.decode('utf-8') - return response + def _call_server(self, url, post_data): + if not url: + response = dict(error=True, message='AttributeError: Bad URL: ' + str(url)) + return json.dumps(response) + data = urlencode(post_data).encode("utf-8") + request = urllib2.Request(url, data) + # print('call_server: ', url, data) + try: + res = urllib2.urlopen(request) + except urllib2.HTTPError as e: + headers = e.headers if self._debug else '' + response = dict( + error=True, + message='HTTPError: {0} {1} {2}'.format(e.code, e.reason, headers), + ) + response = json.dumps(response) + except urllib2.URLError as e: + response = dict(error=True, message='URLError: {0}'.format(e.reason)) + response = json.dumps(response) + except BaseException as e: + response = dict(error=True, message='Error: {0}'.format(e)) + response = json.dumps(response) + else: + res2 = res.read() + response = res2 if isinstance(res2, str) else res2.decode('utf-8') + return response - def request(self, api_name, data): - path = '{version}/{api_name}'.format(version=self.version, api_name=api_name) - response = self._call_server(urljoin(self.url, path), data) - try: - response = json.loads(response) - except ValueError as e: - response = dict(error=True, message=repr(e)) - return response + def request(self, api_name, data): + path = '{version}/{api_name}'.format(version=self.version, api_name=api_name) + response = self._call_server(urljoin(self.url, path), data) + try: + response = json.loads(response) + except ValueError as e: + response = dict(error=True, message=repr(e)) + return response - def post(self, url, data): - response = self._call_server(url, data) - try: - response = json.loads(response) - except ValueError as e: - response = dict(error=True, message=repr(e)) - return response + def post(self, url, data): + response = self._call_server(url, data) + try: + response = json.loads(response) + except ValueError as e: + response = dict(error=True, message=repr(e)) + return response diff --git a/qencode3/metadata.py b/qencode3/metadata.py index c7cae83..b31cee6 100644 --- a/qencode3/metadata.py +++ b/qencode3/metadata.py @@ -1,17 +1,20 @@ -from . task import * +from .task import * from qencode3 import QencodeTaskException import urllib.request as urllib2 -class Metadata(Task): +class Metadata(Task): def get(self, uri): - params = """ + params = ( + """ {"query": { "source": "%s", "format": [ {"output": "metadata", "metadata_version": "4.1.5"} ] } } - """ % uri + """ + % uri + ) self.custom_start(params) while True: status = self.status() @@ -34,5 +37,3 @@ def get(self, uri): data = urllib2.urlopen(url).read() return data - - diff --git a/qencode3/task.py b/qencode3/task.py index 1b2b526..d4da2b8 100644 --- a/qencode3/task.py +++ b/qencode3/task.py @@ -1,29 +1,28 @@ -from . custom_params import Query, CustomTranscodingParams -from . const import * +from .custom_params import Query, CustomTranscodingParams +from .const import * import time import json -from . utils import is_json, rm_key_if_null - +from .utils import is_json, rm_key_if_null class Task(object): - def __init__(self, access_token, connect, debug=False, **kwargs): - self.connect = connect - self.status_url = None - self.main_status_url = '{0}/{1}/status'.format(self.connect.url, self.connect.version) - self.task_token = None - self.upload_url = None - self.access_token = access_token - self._debug = debug - self.message = '' - self.error = None - self.repeat = kwargs.get('repeats') if kwargs.get('repeats') else REPEAT - self._create_task(1) - - - - def start(self, profiles, video_url, **kwargs): - """Creating task and starting encode + def __init__(self, access_token, connect, debug=False, **kwargs): + self.connect = connect + self.status_url = None + self.main_status_url = '{0}/{1}/status'.format( + self.connect.url, self.connect.version + ) + self.task_token = None + self.upload_url = None + self.access_token = access_token + self._debug = debug + self.message = '' + self.error = None + self.repeat = kwargs.get('repeats') if kwargs.get('repeats') else REPEAT + self._create_task(1) + + def start(self, profiles, video_url, **kwargs): + """Creating task and starting encode :param profiles: String or List object. Profile uuid :param transfer_method: String. Transfer method uuid @@ -32,178 +31,174 @@ def start(self, profiles, video_url, **kwargs): :return: None """ - if not self.error: - #self._create_task(1) - data = self._prepare_data(profiles, video_url, **kwargs) - - if not self.error and self.task_token: - self._start_encode('start_encode', data) + if not self.error: + # self._create_task(1) + data = self._prepare_data(profiles, video_url, **kwargs) + if not self.error and self.task_token: + self._start_encode('start_encode', data) - def custom_start(self, data, **kwargs): - """Creating task and starting encode + def custom_start(self, data, **kwargs): + """Creating task and starting encode :param query: JSON object for query param. For examples: https://docs.qencode.com :param payload: String. :return: None """ - if data is None: - self.error = True - self.message = 'Params is required' - - #if not self.error: - # self._create_task(1) - - if not self.error: - query = self._prepare_query(data) - - if not self.error: - data = self._prepare_data_custom(query, **kwargs) - - if not self.error and self.task_token: - self._start_encode('start_encode2', data) - - - def status(self): - return self._status() - - def main_status(self): - return self._status2() - - def progress_changed(self, callback, *args, **kwargs): - while 1: - status = self._status() - if status['error']: - return callback(status, *args, **kwargs) - callback(status, *args, **kwargs) - if status.get('status') in COMPLETED_STATUS: - break - time.sleep(SLEEP_REGULAR) - - - def task_completed(self, callback, *args, **kwargs): - while 1: - status = self._status() - if status['error']: - return callback(status, *args, **kwargs) - if status.get('status') in COMPLETED_STATUS: - return callback(status, *args, **kwargs) - if status.get('status') in COMPLETED_STATUS: - break - time.sleep(SLEEP_REGULAR) - - - def _prepare_data(self, profiles, video_url, **kwargs): - data = dict( - task_token=self.task_token, - profiles=', '.join(profiles) if type(profiles).__name__ == 'list' else profiles - ) - if isinstance(video_url, list): - try: - data.update(stitch=json.dumps(video_url)) - except Exception: - data.update(stitch=video_url) - else: - data.update(uri=video_url) - if kwargs: - data.update(kwargs) - return data - - def _prepare_query(self, params): - if isinstance(params, CustomTranscodingParams): - query_obj = Query() - query_obj.params = params - query_obj.validate_params() - if query_obj.error: - self.error = query_obj.error - self.message = query_obj.message - query_obj.prepare_params() - if query_obj.error: - self.error = query_obj.error - self.message = query_obj.message - return query_obj.query - - if isinstance(params, dict): - query = rm_key_if_null(params) - return json.dumps(query) - - if isinstance(params, (str, bytes)): - if is_json(params): - query = rm_key_if_null(params) - return query - else: - self.error = True - try: - self.message = "JSON is not well formatted: {0} Is not defined".format(params) - except Exception as e: - pass - finally: - self.message = "JSON is not well formatted" - - def _prepare_data_custom(self, query_json, **kwargs): - data = dict( - task_token=self.task_token, - query=query_json - ) - if kwargs: - data.update(kwargs) - return data - - - def _create_task(self, count): - res = self.connect.request('create_task', dict(token=self.access_token)) - if not res['error']: - self.task_token = res.get('task_token') - self.upload_url = res.get('upload_url') - else: - self.error = res['error'] - self.message = res.get('message') - - if self.error and self.error == 8: - if count < REPEAT: - time.sleep(SLEEP_ERROR) - self._create_task(count + 1) - - def _start_encode(self, api_name, data): - res = self.connect.request(api_name, data) - if not res['error'] and res.get('status_url'): - self.status_url = res['status_url'] - else: - self.status_url = self.main_status_url - self.error = res.get('error') - self.message = res.get('message') - - def _status(self): - response = self.connect.post(self.status_url, dict(task_tokens=self.task_token)) - status = None - - if response['error'] == ERROR_BAD_TOKENS: - raise ValueError('Bad token: ' + str(self.task_token)) - - if 'statuses' in response and self.task_token in response['statuses']: - status = response['statuses'][self.task_token] - - if not status and self.status_url != self.main_status_url: - self.status_url = self.main_status_url - response = self.connect.post(self.status_url, dict(task_tokens=self.task_token)) - if 'statuses' in response and self.task_token in response['statuses']: - status = response['statuses'][self.task_token] - - if status and 'status_url' in status: - self.status_url = status['status_url'] - - return status - - - # def _status2(self): - # response = self.connect.request('status', {'task_tokens[]': self.task_token}) - # if not response['error']: - # res = response['statuses'][self.task_token] - # if res: - # return res - # else: - # return dict(error=True, message='Error getting status') - # else: - # return response - + if data is None: + self.error = True + self.message = 'Params is required' + + # if not self.error: + # self._create_task(1) + + if not self.error: + query = self._prepare_query(data) + + if not self.error: + data = self._prepare_data_custom(query, **kwargs) + + if not self.error and self.task_token: + self._start_encode('start_encode2', data) + + def status(self): + return self._status() + + def main_status(self): + return self._status2() + + def progress_changed(self, callback, *args, **kwargs): + while 1: + status = self._status() + if status['error']: + return callback(status, *args, **kwargs) + callback(status, *args, **kwargs) + if status.get('status') in COMPLETED_STATUS: + break + time.sleep(SLEEP_REGULAR) + + def task_completed(self, callback, *args, **kwargs): + while 1: + status = self._status() + if status['error']: + return callback(status, *args, **kwargs) + if status.get('status') in COMPLETED_STATUS: + return callback(status, *args, **kwargs) + if status.get('status') in COMPLETED_STATUS: + break + time.sleep(SLEEP_REGULAR) + + def _prepare_data(self, profiles, video_url, **kwargs): + data = dict( + task_token=self.task_token, + profiles=', '.join(profiles) + if type(profiles).__name__ == 'list' + else profiles, + ) + if isinstance(video_url, list): + try: + data.update(stitch=json.dumps(video_url)) + except Exception: + data.update(stitch=video_url) + else: + data.update(uri=video_url) + if kwargs: + data.update(kwargs) + return data + + def _prepare_query(self, params): + if isinstance(params, CustomTranscodingParams): + query_obj = Query() + query_obj.params = params + query_obj.validate_params() + if query_obj.error: + self.error = query_obj.error + self.message = query_obj.message + query_obj.prepare_params() + if query_obj.error: + self.error = query_obj.error + self.message = query_obj.message + return query_obj.query + + if isinstance(params, dict): + query = rm_key_if_null(params) + return json.dumps(query) + + if isinstance(params, (str, bytes)): + if is_json(params): + query = rm_key_if_null(params) + return query + else: + self.error = True + try: + self.message = "JSON is not well formatted: {0} Is not defined".format( + params + ) + except Exception as e: + pass + finally: + self.message = "JSON is not well formatted" + + def _prepare_data_custom(self, query_json, **kwargs): + data = dict(task_token=self.task_token, query=query_json) + if kwargs: + data.update(kwargs) + return data + + def _create_task(self, count): + res = self.connect.request('create_task', dict(token=self.access_token)) + if not res['error']: + self.task_token = res.get('task_token') + self.upload_url = res.get('upload_url') + else: + self.error = res['error'] + self.message = res.get('message') + + if self.error and self.error == 8: + if count < REPEAT: + time.sleep(SLEEP_ERROR) + self._create_task(count + 1) + + def _start_encode(self, api_name, data): + res = self.connect.request(api_name, data) + if not res['error'] and res.get('status_url'): + self.status_url = res['status_url'] + else: + self.status_url = self.main_status_url + self.error = res.get('error') + self.message = res.get('message') + + def _status(self): + response = self.connect.post(self.status_url, dict(task_tokens=self.task_token)) + status = None + + if response['error'] == ERROR_BAD_TOKENS: + raise ValueError('Bad token: ' + str(self.task_token)) + + if 'statuses' in response and self.task_token in response['statuses']: + status = response['statuses'][self.task_token] + + if not status and self.status_url != self.main_status_url: + self.status_url = self.main_status_url + response = self.connect.post( + self.status_url, dict(task_tokens=self.task_token) + ) + if 'statuses' in response and self.task_token in response['statuses']: + status = response['statuses'][self.task_token] + + if status and 'status_url' in status: + self.status_url = status['status_url'] + + return status + + # def _status2(self): + # response = self.connect.request('status', {'task_tokens[]': self.task_token}) + # if not response['error']: + # res = response['statuses'][self.task_token] + # if res: + # return res + # else: + # return dict(error=True, message='Error getting status') + # else: + # return response diff --git a/qencode3/tools.py b/qencode3/tools.py index 92d2c33..16e469b 100644 --- a/qencode3/tools.py +++ b/qencode3/tools.py @@ -5,7 +5,10 @@ import requests from requests.utils import quote -def generate_aws_signed_url(region, bucket, object_key, access_key, secret_key, expiration, endpoint=None): + +def generate_aws_signed_url( + region, bucket, object_key, access_key, secret_key, expiration, endpoint=None +): # request elements http_method = 'GET' @@ -31,11 +34,21 @@ def createSignatureKey(key, datestamp, region, service): timestamp = time.strftime('%Y%m%dT%H%M%SZ') datestamp = time.strftime('%Y%m%d') - standardized_querystring = ('X-Amz-Algorithm=AWS4-HMAC-SHA256' + - '&X-Amz-Credential=' + access_key + '/' + datestamp + '/' + region + '/s3/aws4_request' + - '&X-Amz-Date=' + timestamp + - '&X-Amz-Expires=' + str(expiration) + - '&X-Amz-SignedHeaders=host') + standardized_querystring = ( + 'X-Amz-Algorithm=AWS4-HMAC-SHA256' + + '&X-Amz-Credential=' + + access_key + + '/' + + datestamp + + '/' + + region + + '/s3/aws4_request' + + '&X-Amz-Date=' + + timestamp + + '&X-Amz-Expires=' + + str(expiration) + + '&X-Amz-SignedHeaders=host' + ) standardized_querystring_url_encoded = quote(standardized_querystring, safe='&=') standardized_resource = '/' + object_key @@ -45,35 +58,51 @@ def createSignatureKey(key, datestamp, region, service): standardized_headers = 'host:' + host signed_headers = 'host' - standardized_request = (http_method + '\n' + - standardized_resource + '\n' + - standardized_querystring_url_encoded + '\n' + - standardized_headers + '\n' + - '\n' + - signed_headers + '\n' + - payload_hash).encode('utf-8') + standardized_request = ( + http_method + + '\n' + + standardized_resource + + '\n' + + standardized_querystring_url_encoded + + '\n' + + standardized_headers + + '\n' + + '\n' + + signed_headers + + '\n' + + payload_hash + ).encode('utf-8') # assemble string-to-sign hashing_algorithm = 'AWS4-HMAC-SHA256' credential_scope = datestamp + '/' + region + '/' + 's3' + '/' + 'aws4_request' - sts = (hashing_algorithm + '\n' + - timestamp + '\n' + - credential_scope + '\n' + - hashlib.sha256(standardized_request).hexdigest()) + sts = ( + hashing_algorithm + + '\n' + + timestamp + + '\n' + + credential_scope + + '\n' + + hashlib.sha256(standardized_request).hexdigest() + ) # generate the signature signature_key = createSignatureKey(secret_key, datestamp, region, 's3') - signature = hmac.new(signature_key, - (sts).encode('utf-8'), - hashlib.sha256).hexdigest() + signature = hmac.new( + signature_key, (sts).encode('utf-8'), hashlib.sha256 + ).hexdigest() # create and send the request # the 'requests' package autmatically adds the required 'host' header - request_url = (endpoint + '/' + - object_key + '?' + - standardized_querystring_url_encoded + - '&X-Amz-Signature=' + - signature) + request_url = ( + endpoint + + '/' + + object_key + + '?' + + standardized_querystring_url_encoded + + '&X-Amz-Signature=' + + signature + ) def hex_hash(key, msg): return hmac.new(b'key', msg.encode('utf-8'), hashlib.sha256).hexdigest() @@ -88,4 +117,4 @@ def createHexSignatureKey(key, datestamp, region, service): signature_key_hex = createHexSignatureKey(secret_key, datestamp, region, 's3') # print(request_url) - return request_url \ No newline at end of file + return request_url diff --git a/qencode3/utils.py b/qencode3/utils.py index 1268010..5ed8e8f 100644 --- a/qencode3/utils.py +++ b/qencode3/utils.py @@ -2,68 +2,81 @@ import logging import json + def is_number(s): - try: - float(s) - return True - except: - return False + try: + float(s) + return True + except: + return False + def get_percent(p): - if is_number(p): - return round(p) - return 0 + if is_number(p): + return round(p) + return 0 + def is_json(value): - try: - json.loads(value) - except ValueError: - return False - return True + try: + json.loads(value) + except ValueError: + return False + return True + def rm_attributes_if_null(class_obj): - for key, val in class_obj.__dict__.copy().items(): - if not val: - class_obj.__dict__.pop(key) + for key, val in class_obj.__dict__.copy().items(): + if not val: + class_obj.__dict__.pop(key) + def rm_key_if_null(obj): - if isinstance(obj, dict): - return _rm_key(obj) - elif isinstance(obj, (str, bytes)): - res = _rm_key(json.loads(obj)) - return json.dumps(res) + if isinstance(obj, dict): + return _rm_key(obj) + elif isinstance(obj, (str, bytes)): + res = _rm_key(json.loads(obj)) + return json.dumps(res) + def _rm_key(_dict): - for key, val in _dict.copy().items(): - if not val: - _dict.pop(key) - return _dict + for key, val in _dict.copy().items(): + if not val: + _dict.pop(key) + return _dict def progress_bar(self, custom_message=None): - message = custom_message if custom_message else '' - while 1: - barLength, status = 20, "" - progress = float(self.percent) / 100.0 - if progress >= 1.: - progress, status = 1, "\r\n" - block = int(round(barLength * progress)) - text = "\r{} [{}] {:.0f}% {}".format(message, - "#" * block + "-" * (barLength - block), round(progress * 100, 0), status) - sys.stdout.write(text) - sys.stdout.flush() - if self.task_completed: - break + message = custom_message if custom_message else '' + while 1: + barLength, status = 20, "" + progress = float(self.percent) / 100.0 + if progress >= 1.0: + progress, status = 1, "\r\n" + block = int(round(barLength * progress)) + text = "\r{} [{}] {:.0f}% {}".format( + message, + "#" * block + "-" * (barLength - block), + round(progress * 100, 0), + status, + ) + sys.stdout.write(text) + sys.stdout.flush() + if self.task_completed: + break + def log(self, path=None, name=None, log_format=None): - format = '[%(asctime)s] %(levelname)s %(message)s' if not log_format else log_format - name = name if name else '{0}.log'.format(self.task.token) - path = path if path else '' - log_name = '{0}{1}'.format(path, name) - logging.basicConfig(filename=log_name, format=format()) - logging.getLogger().setLevel(logging.INFO) - log = logging.getLogger() - while 1: - log.info('{0} | {1} | {2}'.format(self.status, self.percent, self.message)) - if self.task_completed: - break \ No newline at end of file + format = ( + '[%(asctime)s] %(levelname)s %(message)s' if not log_format else log_format + ) + name = name if name else '{0}.log'.format(self.task.token) + path = path if path else '' + log_name = '{0}{1}'.format(path, name) + logging.basicConfig(filename=log_name, format=format()) + logging.getLogger().setLevel(logging.INFO) + log = logging.getLogger() + while 1: + log.info('{0} | {1} | {2}'.format(self.status, self.percent, self.message)) + if self.task_completed: + break diff --git a/sample-code/metadata.py b/sample-code/metadata.py index 7434fa0..2d204b2 100644 --- a/sample-code/metadata.py +++ b/sample-code/metadata.py @@ -3,12 +3,15 @@ import sys import os.path -#import json -sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir))) + +# import json +sys.path.append( + os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir)) +) import qencode3 from qencode3 import QencodeClientException -#replace with your API KEY (can be found in your Project settings on Qencode portal) +# replace with your API KEY (can be found in your Project settings on Qencode portal) API_KEY = '' VIDEO_URL = 'https://nyc3.s3.qencode.com/qencode/bbb_30s.mp4' @@ -21,11 +24,8 @@ metadata = client.get_metadata(VIDEO_URL) try: - metadata = metadata.decode("utf-8") + metadata = metadata.decode("utf-8") except Exception as e: pass print(metadata) - - - diff --git a/sample-code/start_custom_hls.py b/sample-code/start_custom_hls.py index 334ddf9..8ed7f7c 100644 --- a/sample-code/start_custom_hls.py +++ b/sample-code/start_custom_hls.py @@ -3,13 +3,16 @@ import sys import os.path -sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir))) + +sys.path.append( + os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir)) +) import qencode3 import time import json from qencode3 import QencodeClientException, QencodeTaskException -#replace with your API KEY (can be found in your Project settings on Qencode portal) +# replace with your API KEY (can be found in your Project settings on Qencode portal) API_KEY = 'your-api-qencode-key' params = qencode3.custom_params() @@ -34,13 +37,14 @@ FORMAT.output = "advanced_hls" FORMAT.destination = DESTINATION -#replace with a link to your input video +# replace with a link to your input video params.source = 'https://qencode.com/static/1.mp4' params.format = [FORMAT] + def start_encode(): - """ + """ Create client object :param api_key: string. required :param api_url: string. not required @@ -48,33 +52,34 @@ def start_encode(): :return: task object """ - client = qencode3.client(API_KEY) - if client.error: - raise QencodeClientException(client.message) + client = qencode3.client(API_KEY) + if client.error: + raise QencodeClientException(client.message) + + print('The client created. Expire date: {0}'.format(client.expire)) - print('The client created. Expire date: {0}'.format(client.expire)) + task = client.create_task() - task = client.create_task() + if task.error: + raise QencodeTaskException(task.message) - if task.error: - raise QencodeTaskException(task.message) + task.custom_start(params) - task.custom_start(params) + if task.error: + raise QencodeTaskException(task.message) - if task.error: - raise QencodeTaskException(task.message) + print('Start encode. Task: {0}'.format(task.task_token)) - print('Start encode. Task: {0}'.format(task.task_token)) + line = "-" * 80 + while True: + print(line) + status = task.status() + # print status + print(json.dumps(status, indent=2, sort_keys=True)) + if status['error'] or status['status'] == 'completed': + break + time.sleep(5) - line = "-" * 80 - while True: - print(line) - status = task.status() - # print status - print(json.dumps(status, indent=2, sort_keys=True)) - if status['error'] or status['status'] == 'completed': - break - time.sleep(5) if __name__ == '__main__': - start_encode() + start_encode() diff --git a/sample-code/start_custom_mp4.py b/sample-code/start_custom_mp4.py index 36f6ad3..fa3fc93 100644 --- a/sample-code/start_custom_mp4.py +++ b/sample-code/start_custom_mp4.py @@ -3,13 +3,16 @@ import sys import os.path -sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir))) + +sys.path.append( + os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir)) +) import qencode3 import time import json from qencode3 import QencodeClientException, QencodeTaskException -#replace with your API KEY (can be found in your Project settings on Qencode portal) +# replace with your API KEY (can be found in your Project settings on Qencode portal) API_KEY = 'your-api-qencode-key' params = qencode3.custom_params() @@ -27,13 +30,14 @@ FORMAT.output = "mp4" FORMAT.destination = DESTINATION -#replace with a link to your input video +# replace with a link to your input video params.source = 'https://qencode.com/static/1.mp4' params.format = [FORMAT] + def start_encode(): - """ + """ Create client object :param api_key: string. required :param api_url: string. not required @@ -41,33 +45,34 @@ def start_encode(): :return: task object """ - client = qencode3.client(API_KEY) - if client.error: - raise QencodeClientException(client.message) + client = qencode3.client(API_KEY) + if client.error: + raise QencodeClientException(client.message) + + print('The client created. Expire date: {0}'.format(client.expire)) - print('The client created. Expire date: {0}'.format(client.expire)) + task = client.create_task() - task = client.create_task() + if task.error: + raise QencodeTaskException(task.message) - if task.error: - raise QencodeTaskException(task.message) + task.custom_start(params) - task.custom_start(params) + if task.error: + raise QencodeTaskException(task.message) - if task.error: - raise QencodeTaskException(task.message) + print('Start encode. Task: {0}'.format(task.task_token)) - print('Start encode. Task: {0}'.format(task.task_token)) + line = "-" * 80 + while True: + print(line) + status = task.status() + # print status + print(json.dumps(status, indent=2, sort_keys=True)) + if status['error'] or status['status'] == 'completed': + break + time.sleep(5) - line = "-"*80 - while True: - print(line) - status = task.status() - # print status - print(json.dumps(status, indent=2, sort_keys=True)) - if status['error'] or status['status'] == 'completed': - break - time.sleep(5) if __name__ == '__main__': - start_encode() + start_encode() diff --git a/sample-code/start_custom_with_dict.py b/sample-code/start_custom_with_dict.py index 7b3f934..cfc80ab 100644 --- a/sample-code/start_custom_with_dict.py +++ b/sample-code/start_custom_with_dict.py @@ -3,42 +3,35 @@ import sys import os.path -sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir))) + +sys.path.append( + os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir)) +) import qencode3 import time import json from qencode3 import QencodeClientException, QencodeTaskException -#replace with your API KEY (can be found in your Project settings on Qencode portal) +# replace with your API KEY (can be found in your Project settings on Qencode portal) API_KEY = 'your-api-qencode-key' -#replace with a link to your input video +# replace with a link to your input video source_url = "https://qencode.com/static/1.mp4" -format_240 = dict( - output="mp4", - size="320x240", - video_codec="libx264" -) +format_240 = dict(output="mp4", size="320x240", video_codec="libx264") -format_720 = dict( - output="mp4", - size="1280x720", - video_codec="libx264" -) +format_720 = dict(output="mp4", size="1280x720", video_codec="libx264") format = [format_240, format_720] -query = dict( - source=source_url, - format=format -) +query = dict(source=source_url, format=format) params = dict(query=query) + def start_encode(): - """ + """ Create client object :param api_key: string. required :param api_url: string. not required @@ -46,34 +39,34 @@ def start_encode(): :return: task object """ + client = qencode3.client(API_KEY) + if client.error: + raise QencodeClientException(client.message) - client = qencode3.client(API_KEY) - if client.error: - raise QencodeClientException(client.message) + print('The client created. Expire date: {0}'.format(client.expire)) - print('The client created. Expire date: {0}'.format(client.expire)) + task = client.create_task() - task = client.create_task() + if task.error: + raise QencodeTaskException(task.message) - if task.error: - raise QencodeTaskException(task.message) + task.custom_start(params) - task.custom_start(params) + if task.error: + raise QencodeTaskException(task.message) - if task.error: - raise QencodeTaskException(task.message) + print('Start encode. Task: {0}'.format(task.task_token)) - print('Start encode. Task: {0}'.format(task.task_token)) + line = "-" * 80 + while True: + print(line) + status = task.status() + # print status + print(json.dumps(status, indent=2, sort_keys=True)) + if status['error'] or status['status'] == 'completed': + break + time.sleep(5) - line = "-"*80 - while True: - print(line) - status = task.status() - # print status - print(json.dumps(status, indent=2, sort_keys=True)) - if status['error'] or status['status'] == 'completed': - break - time.sleep(5) if __name__ == '__main__': - start_encode() + start_encode() diff --git a/sample-code/start_custom_with_file.py b/sample-code/start_custom_with_file.py index 1cd3904..a8f49bc 100644 --- a/sample-code/start_custom_with_file.py +++ b/sample-code/start_custom_with_file.py @@ -3,31 +3,39 @@ import sys import os.path -sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir))) + +sys.path.append( + os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir)) +) import qencode3 import time import json from qencode3 import QencodeClientException, QencodeTaskException -#replace with your API KEY (can be found in your Project settings on Qencode portal) +# replace with your API KEY (can be found in your Project settings on Qencode portal) API_KEY = 'your-api-qencode-key' + def get_query_template(): - try: - with open(os.path.abspath(os.path.join(os.path.dirname(__file__), 'query.json'))) as data: - try: - file_data = json.load(data) - return json.dumps(file_data) - except ValueError as e: + try: + with open( + os.path.abspath(os.path.join(os.path.dirname(__file__), 'query.json')) + ) as data: + try: + file_data = json.load(data) + return json.dumps(file_data) + except ValueError as e: + print(e) + except IOError as e: print(e) - except IOError as e: - print(e) + params = get_query_template() + def start_encode(): - """ + """ Create client object :param api_key: string. required :param api_url: string. not required @@ -35,34 +43,34 @@ def start_encode(): :return: task object """ + client = qencode3.client(API_KEY) + if client.error: + raise QencodeClientException(client.message) - client = qencode3.client(API_KEY) - if client.error: - raise QencodeClientException(client.message) + print('The client created. Expire date: {0}'.format(client.expire)) - print('The client created. Expire date: {0}'.format(client.expire)) + task = client.create_task() - task = client.create_task() + if task.error: + raise QencodeTaskException(task.message) - if task.error: - raise QencodeTaskException(task.message) + task.custom_start(params) - task.custom_start(params) + if task.error: + raise QencodeTaskException(task.message) - if task.error: - raise QencodeTaskException(task.message) + print('Start encode. Task: {0}'.format(task.task_token)) - print('Start encode. Task: {0}'.format(task.task_token)) + line = "-" * 80 + while True: + print(line) + status = task.status() + # print status + print(json.dumps(status, indent=2, sort_keys=True)) + if status['error'] or status['status'] == 'completed': + break + time.sleep(5) - line = "-"*80 - while True: - print(line) - status = task.status() - # print status - print(json.dumps(status, indent=2, sort_keys=True)) - if status['error'] or status['status'] == 'completed': - break - time.sleep(5) if __name__ == '__main__': - start_encode() + start_encode() diff --git a/sample-code/start_custom_with_json.py b/sample-code/start_custom_with_json.py index 74abe5e..02a01be 100644 --- a/sample-code/start_custom_with_json.py +++ b/sample-code/start_custom_with_json.py @@ -3,16 +3,19 @@ import sys import os.path -sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir))) + +sys.path.append( + os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir)) +) import qencode3 import time import json from qencode3 import QencodeClientException, QencodeTaskException -#replace with your API KEY (can be found in your Project settings on Qencode portal) +# replace with your API KEY (can be found in your Project settings on Qencode portal) API_KEY = 'your-api-qencode-key' -#replace with a link to your input video +# replace with a link to your input video params = """ {"query": { "source": "https://qencode.com/static/1.mp4", @@ -27,9 +30,10 @@ } """ + def start_encode(): - """ + """ Create client object :param api_key: string. required :param api_url: string. not required @@ -37,33 +41,34 @@ def start_encode(): :return: task object """ - client = qencode3.client(API_KEY) - if client.error: - raise QencodeClientException(client.message) + client = qencode3.client(API_KEY) + if client.error: + raise QencodeClientException(client.message) + + print('The client created. Expire date: {0}'.format(client.expire)) - print('The client created. Expire date: {0}'.format(client.expire)) + task = client.create_task() - task = client.create_task() + if task.error: + raise QencodeTaskException(task.message) - if task.error: - raise QencodeTaskException(task.message) + task.custom_start(params) - task.custom_start(params) + if task.error: + raise QencodeTaskException(task.message) - if task.error: - raise QencodeTaskException(task.message) + print('Start encode. Task: {0}'.format(task.task_token)) - print('Start encode. Task: {0}'.format(task.task_token)) + line = "-" * 80 + while True: + print(line) + status = task.status() + # print status + print(json.dumps(status, indent=2, sort_keys=True)) + if status['error'] or status['status'] == 'completed': + break + time.sleep(5) - line = "-"*80 - while True: - print(line) - status = task.status() - # print status - print(json.dumps(status, indent=2, sort_keys=True)) - if status['error'] or status['status'] == 'completed': - break - time.sleep(5) if __name__ == '__main__': - start_encode() + start_encode() diff --git a/sample-code/start_encode.py b/sample-code/start_encode.py index bcb45b1..ee6ab44 100644 --- a/sample-code/start_encode.py +++ b/sample-code/start_encode.py @@ -3,26 +3,29 @@ import sys import os.path -sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir))) + +sys.path.append( + os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir)) +) import qencode3 import time import json -from qencode3 import QencodeClientException, QencodeTaskException +from qencode3 import QencodeClientException, QencodeTaskException -#replace with your API KEY (can be found in your Project settings on Qencode portal) +# replace with your API KEY (can be found in your Project settings on Qencode portal) API_KEY = 'your-api-qencode-key' -#replace with your Transcoding Profile ID (can be found in your Project settings on Qencode portal) +# replace with your Transcoding Profile ID (can be found in your Project settings on Qencode portal) TRANSCODING_PROFILEID = 'your-qencode-profile-id' -#replace with a link to your input video +# replace with a link to your input video VIDEO_URL = 'https://qencode.com/static/1.mp4' -#or stitch -#STITCH = ['https://qencode.com/static/1.mp4', 'https://qencode.com/static/2.mp4'] +# or stitch +# STITCH = ['https://qencode.com/static/1.mp4', 'https://qencode.com/static/2.mp4'] def start_encode(): - """ + """ Create client object :param api_key: string. required :param api_url: string. not required @@ -30,38 +33,38 @@ def start_encode(): :return: task object """ - client = qencode3.client(API_KEY) - if client.error: - raise QencodeClientException(client.message) + client = qencode3.client(API_KEY) + if client.error: + raise QencodeClientException(client.message) - print('The client created. Expire date: {0}'.format(client.expire)) + print('The client created. Expire date: {0}'.format(client.expire)) - task = client.create_task() - task.start_time = 0.0 - task.duration = 10.0 + task = client.create_task() + task.start_time = 0.0 + task.duration = 10.0 - if task.error: - raise QencodeTaskException(task.message) + if task.error: + raise QencodeTaskException(task.message) - task.start(TRANSCODING_PROFILEID, VIDEO_URL) - #or stitch - #task.start(TRANSCODING_PROFILEID, STITCH) + task.start(TRANSCODING_PROFILEID, VIDEO_URL) + # or stitch + # task.start(TRANSCODING_PROFILEID, STITCH) - if task.error: - raise QencodeTaskException(task.message) + if task.error: + raise QencodeTaskException(task.message) - print('Start encode. Task: {0}'.format(task.task_token)) + print('Start encode. Task: {0}'.format(task.task_token)) - line = "-"*80 - while True: - print(line) - status = task.status() - # print status - print(json.dumps(status, indent=2, sort_keys=True)) - if status['error'] or status['status'] == 'completed': - break - time.sleep(5) + line = "-" * 80 + while True: + print(line) + status = task.status() + # print status + print(json.dumps(status, indent=2, sort_keys=True)) + if status['error'] or status['status'] == 'completed': + break + time.sleep(5) if __name__ == '__main__': - start_encode() \ No newline at end of file + start_encode() diff --git a/sample-code/start_with_aws_signed_url.py b/sample-code/start_with_aws_signed_url.py index 822dc15..98667c4 100644 --- a/sample-code/start_with_aws_signed_url.py +++ b/sample-code/start_with_aws_signed_url.py @@ -3,7 +3,10 @@ import sys import os.path -sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir))) + +sys.path.append( + os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir)) +) import qencode3 import time import json @@ -22,33 +25,25 @@ secret_key = 'your-AWS-secret-key' # generate AWS signed url -source_url = generate_aws_signed_url(region, bucket, object_key, access_key, secret_key, expiration) +source_url = generate_aws_signed_url( + region, bucket, object_key, access_key, secret_key, expiration +) print(source_url) -format_240 = dict( - output="mp4", - size="320x240", - video_codec="libx264" -) +format_240 = dict(output="mp4", size="320x240", video_codec="libx264") -format_720 = dict( - output="mp4", - size="1280x720", - video_codec="libx264" -) +format_720 = dict(output="mp4", size="1280x720", video_codec="libx264") format = [format_240, format_720] -query = dict( - source=source_url, - format=format -) +query = dict(source=source_url, format=format) params = dict(query=query) + def start_encode(): - """ + """ Create client object :param api_key: string. required :param api_url: string. not required @@ -56,34 +51,34 @@ def start_encode(): :return: task object """ + client = qencode3.client(API_KEY) + if client.error: + raise QencodeClientException(client.message) - client = qencode3.client(API_KEY) - if client.error: - raise QencodeClientException(client.message) + print('The client created. Expire date: {0}'.format(client.expire)) - print('The client created. Expire date: {0}'.format(client.expire)) + task = client.create_task() - task = client.create_task() + if task.error: + raise QencodeTaskException(task.message) - if task.error: - raise QencodeTaskException(task.message) + task.custom_start(params) - task.custom_start(params) + if task.error: + raise QencodeTaskException(task.message) - if task.error: - raise QencodeTaskException(task.message) + print('Start encode. Task: {0}'.format(task.task_token)) - print('Start encode. Task: {0}'.format(task.task_token)) + line = "-" * 80 + while True: + print(line) + status = task.status() + # print status + print(json.dumps(status, indent=2, sort_keys=True)) + if status['error'] or status['status'] == 'completed': + break + time.sleep(5) - line = "-"*80 - while True: - print(line) - status = task.status() - # print status - print(json.dumps(status, indent=2, sort_keys=True)) - if status['error'] or status['status'] == 'completed': - break - time.sleep(5) if __name__ == '__main__': - start_encode() + start_encode() diff --git a/sample-code/start_with_callback.py b/sample-code/start_with_callback.py index 7cd2a2e..0334a6c 100644 --- a/sample-code/start_with_callback.py +++ b/sample-code/start_with_callback.py @@ -3,35 +3,37 @@ import sys import os.path -sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir))) + +sys.path.append( + os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir)) +) import qencode3 import json from qencode3 import QencodeClientException, QencodeTaskException - -#replace with your API KEY (can be found in your Project settings on Qencode portal) +# replace with your API KEY (can be found in your Project settings on Qencode portal) API_KEY = 'your-api-qencode-key' -#replace with your Transcoding Profile ID (can be found in your Project settings on Qencode portal) +# replace with your Transcoding Profile ID (can be found in your Project settings on Qencode portal) TRANSCODING_PROFILEID = 'your-qencode-profile-id' -#replace with a link to your input video +# replace with a link to your input video VIDEO_URL = 'https://qa.qencode.com/static/1.mp4' def progress_changed_handler(status): - if status['status'] != 'completed': - print(json.dumps(status, indent=2, sort_keys=True)) + if status['status'] != 'completed': + print(json.dumps(status, indent=2, sort_keys=True)) def task_completed_handler(status, task_token): - print('Completed task: {0}'.format(task_token)) - print(json.dumps(status, indent=2, sort_keys=True)) + print('Completed task: {0}'.format(task_token)) + print(json.dumps(status, indent=2, sort_keys=True)) def start_encode(): - """ + """ Create client object :param api_key: string. required :param api_url: string. not required @@ -39,30 +41,30 @@ def start_encode(): :return: task object """ - client = qencode3.client(API_KEY) - if client.error: - raise QencodeClientException(client.message) + client = qencode3.client(API_KEY) + if client.error: + raise QencodeClientException(client.message) - print('The client created. Expire date: {0}'.format(client.expire)) + print('The client created. Expire date: {0}'.format(client.expire)) - task = client.create_task() - task.start_time = 0.0 - task.duration = 10.0 + task = client.create_task() + task.start_time = 0.0 + task.duration = 10.0 - if task.error: - raise QencodeTaskException(task.message) + if task.error: + raise QencodeTaskException(task.message) - task.start(TRANSCODING_PROFILEID, VIDEO_URL) + task.start(TRANSCODING_PROFILEID, VIDEO_URL) - if task.error: - raise QencodeTaskException(task.message) + if task.error: + raise QencodeTaskException(task.message) - print('Start encode. Task: {0}'.format(task.task_token)) + print('Start encode. Task: {0}'.format(task.task_token)) - # using callback methods - task.progress_changed(progress_changed_handler) - task.task_completed(task_completed_handler, task.task_token) + # using callback methods + task.progress_changed(progress_changed_handler) + task.task_completed(task_completed_handler, task.task_token) if __name__ == '__main__': - start_encode() \ No newline at end of file + start_encode() diff --git a/setup.py b/setup.py index 7d00ccb..d214320 100644 --- a/setup.py +++ b/setup.py @@ -27,9 +27,8 @@ 'Intended Audience :: Developers', 'Topic :: Software Development :: Build Tools', 'License :: Other/Proprietary License', - 'Programming Language :: Python :: 3.6' - + 'Programming Language :: Python :: 3.6', ], keywords='qencode3, qencode.com, cloud.qencode.com', - packages=['qencode3'] -) + packages=['qencode3'], +) diff --git a/tests/test_client.py b/tests/test_client.py index 3d92c88..599b5b6 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -2,15 +2,15 @@ class TestQencodeApiClient(unittest.TestCase): - def setUp(self): - pass + pass def tearDown(self): - pass + pass def test_create_task(self): pass + if __name__ == '__main__': - unittest.main() \ No newline at end of file + unittest.main()