# Path: memsource/constants.py
# class Base(enum.Enum):
# class JobStatus(enum.Enum):
# class ProjectStatus(enum.Enum):
# class AnalysisFormat(enum.Enum):
# class TermBaseFormat(enum.Enum):
# class ApiVersion(enum.Enum):
# class HttpMethod(enum.Enum):
# class BaseRest(enum.Enum):
# class JobStatusRest(enum.Enum):
#     NEW = "New"
#     EMAILED = "Emailed"
#     ASSIGNED = "Assigned"
#     DECLINED_BY_LINGUIST = "Declined_By_Linguist"
#     COMPLETED_BY_LINGUIST = "Completed_By_Linguist"
#     COMPLETED = "Completed"
#     CANCELLED = "Cancelled"
#     NEW = "New"
#     ASSIGNED = "Assigned"
#     COMPLETED = "Completed"
#     CANCELLED = "Cancelled"
#     ACCEPTED_BY_VENDOR = "Accepted_By_Vendor"
#     DECLINED_BY_VENDOR = "Declined_By_Vendor"
#     COMPLETED_BY_VENDOR = "Completed_By_Vendor"
#     CSV = "CSV"
#     LOG = "LOG"
#     CSV_EXTENDED = "CSV_EXTENDED"
#     XLSX = "XLSX"
#     TBX = "TBX"
#     NEW = "NEW"
#     ACCEPTED = "ACCEPTED"
#     DECLINED = "DECLINED"
#     REJECTED = "REJECTED"
#     DELIVERED = "DELIVERED"
#     EMAILED = "EMAILED"
#     COMPLETED = "COMPLETED"
#     CANCELLED = "CANCELLED"
# CHUNK_SIZE = 1024
# CHAR_SET = "UTF-8"
# TM_THRESHOLD = 0.7
# 
# Path: memsource/exceptions.py
# class MemsourceException(Exception):
# class MemsourceApiException(MemsourceException):
# class MemsourceUnsupportedFileException(MemsourceException):
#     def __init__(self, status_code, result_json, url, params):
#     def get_error_code(self):
#     def get_error_description(self):
#     def __init__(self, unsupported_files, original_file_path, url, params):
# 
# Path: memsource/models.py
# class BaseModel(dict):
# class User(BaseModel):
# class Authentication(BaseModel):
# class Client(BaseModel):
# class Domain(BaseModel):
# class Language(BaseModel):
# class Project(BaseModel):
# class Job(BaseModel):
# class JobPart(BaseModel):
# class TranslationMemory(BaseModel):
# class AsynchronousRequest(BaseModel):
# class AsynchronousResponse(BaseModel):
# class Segment(BaseModel):
# class SegmentSearchResult(BaseModel):
# class Analysis(BaseModel):
# class MxliffUnit(BaseModel):
# class TermBase(BaseModel):
#     def __getattr__(self, key):
#     def _iso8601_to_datetime(self, source):
#     def date_created(self):
#     def __init__(self, source):
#     def is_complete(self):
#     def has_error(self):
# 
# Path: memsource/lib/mxliff.py
# class MxliffParser(object):
#     def parse(self, resource: {'XML file content as bytes': bytes}):
#         def to_memsouce_key(s: str) -> str:
#     def parse_group(self, group: objectify.ObjectifiedElement) -> models.MxliffUnit:
#     def parse_tunit_metadata(self, trans_unit: objectify.ObjectifiedElement) -> list:


import io
import os
import os.path
import shutil
import types
import urllib.parse
import uuid
import requests
from typing import (
    Any,
    Dict,
    Iterator,
    List,
    Optional,
    Tuple,
    Union,
)
from memsource import constants, exceptions, models
from memsource.lib import mxliff
            **kwargs: dict
    ) -> Tuple[models.AsynchronousResponse, List[models.JobPart]]:
        """Create new Job on Memsource asynchronously.

        :param project_id: Project ID of target project.
        :param file_path: Absolute path of translation target file.
        :param target_langs: Translation target languages.
        :param callback_url: Memsource will hit this url when finished to create the job.
        :param kwargs: See Memsource official document
        http://wiki.memsource.com/wiki/Job_Asynchronous_API_v2

        :return: models.AsynchronousResponse and list of models.JobPart
        """
        with open(file_path, 'rb') as f:
            files = {
                'file': (os.path.basename(file_path), f),
            }

            result = self._post('job/create', dict(kwargs, **{
                'project': project_id,
                'targetLang': target_langs,
                'callbackUrl': callback_url,
            }), files)

        # unsupported file count is 0 mean success.
        unsupported_files = result.get('unsupportedFiles', [])
        if len(unsupported_files) == 0:
            return (models.AsynchronousRequest(result['asyncRequest']),
                    [models.JobPart(job_parts) for job_parts in result['jobParts']])


# Path: memsource/constants.py
# class Base(enum.Enum):
# class JobStatus(enum.Enum):
# class ProjectStatus(enum.Enum):
# class AnalysisFormat(enum.Enum):
# class TermBaseFormat(enum.Enum):
# class ApiVersion(enum.Enum):
# class HttpMethod(enum.Enum):
# class BaseRest(enum.Enum):
# class JobStatusRest(enum.Enum):
#     NEW = "New"
#     EMAILED = "Emailed"
#     ASSIGNED = "Assigned"
#     DECLINED_BY_LINGUIST = "Declined_By_Linguist"
#     COMPLETED_BY_LINGUIST = "Completed_By_Linguist"
#     COMPLETED = "Completed"
#     CANCELLED = "Cancelled"
#     NEW = "New"
#     ASSIGNED = "Assigned"
#     COMPLETED = "Completed"
#     CANCELLED = "Cancelled"
#     ACCEPTED_BY_VENDOR = "Accepted_By_Vendor"
#     DECLINED_BY_VENDOR = "Declined_By_Vendor"
#     COMPLETED_BY_VENDOR = "Completed_By_Vendor"
#     CSV = "CSV"
#     LOG = "LOG"
#     CSV_EXTENDED = "CSV_EXTENDED"
#     XLSX = "XLSX"
#     TBX = "TBX"
#     NEW = "NEW"
#     ACCEPTED = "ACCEPTED"
#     DECLINED = "DECLINED"
#     REJECTED = "REJECTED"
#     DELIVERED = "DELIVERED"
#     EMAILED = "EMAILED"
#     COMPLETED = "COMPLETED"
#     CANCELLED = "CANCELLED"
# CHUNK_SIZE = 1024
# CHAR_SET = "UTF-8"
# TM_THRESHOLD = 0.7
# 
# Path: memsource/exceptions.py
# class MemsourceException(Exception):
# class MemsourceApiException(MemsourceException):
# class MemsourceUnsupportedFileException(MemsourceException):
#     def __init__(self, status_code, result_json, url, params):
#     def get_error_code(self):
#     def get_error_description(self):
#     def __init__(self, unsupported_files, original_file_path, url, params):
# 
# Path: memsource/models.py
# class BaseModel(dict):
# class User(BaseModel):
# class Authentication(BaseModel):
# class Client(BaseModel):
# class Domain(BaseModel):
# class Language(BaseModel):
# class Project(BaseModel):
# class Job(BaseModel):
# class JobPart(BaseModel):
# class TranslationMemory(BaseModel):
# class AsynchronousRequest(BaseModel):
# class AsynchronousResponse(BaseModel):
# class Segment(BaseModel):
# class SegmentSearchResult(BaseModel):
# class Analysis(BaseModel):
# class MxliffUnit(BaseModel):
# class TermBase(BaseModel):
#     def __getattr__(self, key):
#     def _iso8601_to_datetime(self, source):
#     def date_created(self):
#     def __init__(self, source):
#     def is_complete(self):
#     def has_error(self):
# 
# Path: memsource/lib/mxliff.py
# class MxliffParser(object):
#     def parse(self, resource: {'XML file content as bytes': bytes}):
#         def to_memsouce_key(s: str) -> str:
#     def parse_group(self, group: objectify.ObjectifiedElement) -> models.MxliffUnit:
#     def parse_tunit_metadata(self, trans_unit: objectify.ObjectifiedElement) -> list:


# Path: memsource/api.py
import io
import os
import os.path
import shutil
import types
import urllib.parse
import uuid
import requests
from typing import (
    Any,
    Dict,
    Iterator,
    List,
    Optional,
    Tuple,
    Union,
)
from memsource import constants, exceptions, models
from memsource.lib import mxliff

            **kwargs: dict
    ) -> Tuple[models.AsynchronousResponse, List[models.JobPart]]:
        """Create new Job on Memsource asynchronously.

        :param project_id: Project ID of target project.
        :param file_path: Absolute path of translation target file.
        :param target_langs: Translation target languages.
        :param callback_url: Memsource will hit this url when finished to create the job.
        :param kwargs: See Memsource official document
        http://wiki.memsource.com/wiki/Job_Asynchronous_API_v2

        :return: models.AsynchronousResponse and list of models.JobPart
        """
        with open(file_path, 'rb') as f:
            files = {
                'file': (os.path.basename(file_path), f),
            }

            result = self._post('job/create', dict(kwargs, **{
                'project': project_id,
                'targetLang': target_langs,
                'callbackUrl': callback_url,
            }), files)

        # unsupported file count is 0 mean success.
        unsupported_files = result.get('unsupportedFiles', [])
        if len(unsupported_files) == 0:
            return (models.AsynchronousRequest(result['asyncRequest']),
                    [models.JobPart(job_parts) for job_parts in result['jobParts']])


        raise exceptions.MemsourceUnsupportedFileException(