

import importlib
import inspect
import json
import os
import re
import shutil
import sys
from pathlib import Path
from typing import Dict, Optional, Union
from urllib import request

from huggingface_hub import HfFolder, cached_download, hf_hub_download, model_info
from packaging import version

from .. import __version__
from . import DIFFUSERS_DYNAMIC_MODULE_NAME, HF_MODULES_CACHE, logging


lowerCamelCase      				=     (
    '''https://raw.githubusercontent.com/huggingface/diffusers/{revision}/examples/community/{pipeline}.py'''
)


lowerCamelCase      				=     logging.get_logger(__name__)  # pylint: disable=invalid-name


def        __lowercase    (  ):

				"""simple docstring"""






				__lowerCAmelCase					=							'https://pypi.org/pypi/diffusers/json'
				__lowerCAmelCase					=							json.loads(request.urlopen(_lowercase      ).read()      )['releases'].keys()
				return sorted(_lowercase		,					key=lambda UpperCAmelCase__      : version.Version(_lowercase      )      )


def        __lowercase    (  ):

				"""simple docstring"""






				if HF_MODULES_CACHE in sys.path:
								return

				sys.path.append(_lowercase      )
				os.makedirs(_lowercase		,					exist_ok=_lowercase      )
				__lowerCAmelCase					=							Path(_lowercase      ) / '__init__.py'
				if not init_path.exists():
								init_path.touch()


def        __lowercase    (  UpperCAmelCase__      ):

				"""simple docstring"""






				init_hf_modules()
				__lowerCAmelCase					=							Path(_lowercase      ) / name
				# If the parent module does not exist yet, recursively create it.
				if not dynamic_module_path.parent.exists():
								create_dynamic_module(dynamic_module_path.parent      )
				os.makedirs(_lowercase		,					exist_ok=_lowercase      )
				__lowerCAmelCase					=							dynamic_module_path / '__init__.py'
				if not init_path.exists():
								init_path.touch()


def        __lowercase    (  UpperCAmelCase__      ):

				"""simple docstring"""






				with open(_lowercase		,					'r'		,					encoding='utf-8'      ) as f:
								__lowerCAmelCase					=							f.read()

				# Imports of the form `import .xxx`
				__lowerCAmelCase					=							re.findall('^\s*import\s+\.(\S+)\s*$'		,					_lowercase		,					flags=re.MULTILINE      )
				# Imports of the form `from .xxx import yyy`
				relative_imports += re.findall('^\s*from\s+\.(\S+)\s+import'		,					_lowercase		,					flags=re.MULTILINE      )
				# Unique-ify
				return list(set(_lowercase      )      )


def        __lowercase    (  UpperCAmelCase__      ):

				"""simple docstring"""






				__lowerCAmelCase					=							False
				__lowerCAmelCase					=							[module_file]
				__lowerCAmelCase					=							[]

				# Let's recurse through all relative imports
				while not no_change:
								__lowerCAmelCase					=							[]
								for f in files_to_check:
												new_imports.extend(get_relative_imports(_lowercase      )      )

								__lowerCAmelCase					=							Path(_lowercase      ).parent
								__lowerCAmelCase					=							[str(module_path / m      ) for m in new_imports]
								__lowerCAmelCase					=							[f for f in new_import_files if f not in all_relative_imports]
								__lowerCAmelCase					=							[F"""{f}.py""" for f in new_import_files]

								__lowerCAmelCase					=							len(_lowercase      ) == 0
								all_relative_imports.extend(_lowercase      )

				return all_relative_imports


def        __lowercase    (  UpperCAmelCase__      ):

				"""simple docstring"""






				with open(_lowercase		,					'r'		,					encoding='utf-8'      ) as f:
								__lowerCAmelCase					=							f.read()

				# Imports of the form `import xxx`
				__lowerCAmelCase					=							re.findall('^\s*import\s+(\S+)\s*$'		,					_lowercase		,					flags=re.MULTILINE      )
				# Imports of the form `from xxx import yyy`
				imports += re.findall('^\s*from\s+(\S+)\s+import'		,					_lowercase		,					flags=re.MULTILINE      )
				# Only keep the top-level module
				__lowerCAmelCase					=							[imp.split('.'      )[0] for imp in imports if not imp.startswith('.'      )]

				# Unique-ify and test we got them all
				__lowerCAmelCase					=							list(set(_lowercase      )      )
				__lowerCAmelCase					=							[]
				for imp in imports:
								try:
												importlib.import_module(_lowercase      )
								except ImportError:
												missing_packages.append(_lowercase      )

				if len(_lowercase      ) > 0:
								raise ImportError(
								    'This modeling file requires the following packages that were not found in your environment: '
								    F"""{', '.join(_lowercase      )}. Run `pip install {' '.join(_lowercase      )}`"""      )

				return get_relative_imports(_lowercase      )


def        __lowercase    (  UpperCAmelCase__		,					UpperCAmelCase__      ):

				"""simple docstring"""






				__lowerCAmelCase					=							module_path.replace(os.path.sep		,					'.'      )
				__lowerCAmelCase					=							importlib.import_module(_lowercase      )

				if class_name is None:
								return find_pipeline_class(_lowercase      )
				return getattr(_lowercase		,					_lowercase      )


def        __lowercase    (  UpperCAmelCase__      ):

				"""simple docstring"""






				from ..pipelines import DiffusionPipeline

				__lowerCAmelCase					=							dict(inspect.getmembers(_lowercase		,					inspect.isclass      )      )

				__lowerCAmelCase					=							None
				for cls_name, cls in cls_members.items():
								if (
								    cls_name != DiffusionPipeline.__name__
								    and issubclass(cls		,					_lowercase      )
								    and cls.__module__.split('.'      )[0] != "diffusers"
								):
												if pipeline_class is not None:
																raise ValueError(
																    F"""Multiple classes that inherit from {DiffusionPipeline.__name__} have been found:"""
																    F""" {pipeline_class.__name__}, and {cls_name}. Please make sure to define only one in"""
																    F""" {loaded_module}."""      )
												__lowerCAmelCase					=							cls

				return pipeline_class


def        __lowercase    (  UpperCAmelCase__		,					UpperCAmelCase__		,					UpperCAmelCase__ = None		,					UpperCAmelCase__ = False		,					UpperCAmelCase__ = False		,					UpperCAmelCase__ = None		,					UpperCAmelCase__ = None		,					UpperCAmelCase__ = None		,					UpperCAmelCase__ = False		,					):

				"""simple docstring"""






				__lowerCAmelCase					=							str(_lowercase      )

				__lowerCAmelCase					=							os.path.join(_lowercase		,					_lowercase      )

				if os.path.isfile(_lowercase      ):
								__lowerCAmelCase					=							module_file_or_url
								__lowerCAmelCase					=							'local'
				elif pretrained_model_name_or_path.count('/'      ) == 0:
								__lowerCAmelCase					=							get_diffusers_versions()
								# cut ".dev0"
								__lowerCAmelCase					=							'v' + '.'.join(__version__.split('.'      )[:3]      )

								# retrieve github version that matches
								if revision is None:
												__lowerCAmelCase					=							latest_version if latest_version[1:] in available_versions else 'main'
												logger.info(F"""Defaulting to latest_version: {revision}."""      )
								elif revision in available_versions:
												__lowerCAmelCase					=							F"""v{revision}"""
								elif revision == "main":
												__lowerCAmelCase					=							revision
								else:
												raise ValueError(
												    F"""`custom_revision`: {revision} does not exist. Please make sure to choose one of"""
												    F""" {', '.join(available_versions + ['main']      )}."""      )

								# community pipeline on GitHub
								__lowerCAmelCase					=							COMMUNITY_PIPELINES_URL.format(revision=_lowercase		,					pipeline=_lowercase      )
								try:
												__lowerCAmelCase					=							cached_download(
												    _lowercase		,					cache_dir=_lowercase		,					force_download=_lowercase		,					proxies=_lowercase		,					resume_download=_lowercase		,					local_files_only=_lowercase		,					use_auth_token=_lowercase		,					)
												__lowerCAmelCase					=							'git'
												__lowerCAmelCase					=							pretrained_model_name_or_path + '.py'
								except EnvironmentError:
												logger.error(F"""Could not locate the {module_file} inside {pretrained_model_name_or_path}."""      )
												raise
				else:
								try:
												# Load from URL or cache if already cached
												__lowerCAmelCase					=							hf_hub_download(
												    _lowercase		,					_lowercase		,					cache_dir=_lowercase		,					force_download=_lowercase		,					proxies=_lowercase		,					resume_download=_lowercase		,					local_files_only=_lowercase		,					use_auth_token=_lowercase		,					)
												__lowerCAmelCase					=							os.path.join('local'		,					'--'.join(pretrained_model_name_or_path.split('/'      )      )      )
								except EnvironmentError:
												logger.error(F"""Could not locate the {module_file} inside {pretrained_model_name_or_path}."""      )
												raise

    # Check we have all the requirements in our environment
				__lowerCAmelCase					=							check_imports(_lowercase      )

				# Now we move the module inside our cached dynamic modules.
				__lowerCAmelCase					=							DIFFUSERS_DYNAMIC_MODULE_NAME + os.path.sep + submodule
				create_dynamic_module(_lowercase      )
				__lowerCAmelCase					=							Path(_lowercase      ) / full_submodule
				if submodule == "local" or submodule == "git":
								# We always copy local files (we could hash the file to see if there was a change, and give them the name of
								# that hash, to only copy when there is a modification but it seems overkill for now).
								# The only reason we do the copy is to avoid putting too many folders in sys.path.
								shutil.copy(_lowercase		,					submodule_path / module_file      )
								for module_needed in modules_needed:
												__lowerCAmelCase					=							F"""{module_needed}.py"""
												shutil.copy(os.path.join(_lowercase		,					_lowercase      )		,					submodule_path / module_needed      )
				else:
								# Get the commit hash
								# TODO: we will get this info in the etag soon, so retrieve it from there and not here.
								if isinstance(_lowercase		,					_lowercase      ):
												__lowerCAmelCase					=							use_auth_token
								elif use_auth_token is True:
												__lowerCAmelCase					=							HfFolder.get_token()
								else:
												__lowerCAmelCase					=							None

								__lowerCAmelCase					=							model_info(_lowercase		,					revision=_lowercase		,					token=_lowercase      ).sha

								# The module file will end up being placed in a subfolder with the git hash of the repo. This way we get the
								# benefit of versioning.
								__lowerCAmelCase					=							submodule_path / commit_hash
								__lowerCAmelCase					=							full_submodule + os.path.sep + commit_hash
								create_dynamic_module(_lowercase      )

								if not (submodule_path / module_file).exists():
												shutil.copy(_lowercase		,					submodule_path / module_file      )
								# Make sure we also have every file with relative
								for module_needed in modules_needed:
												if not (submodule_path / module_needed).exists():
																get_cached_module_file(
																    _lowercase		,					F"""{module_needed}.py"""		,					cache_dir=_lowercase		,					force_download=_lowercase		,					resume_download=_lowercase		,					proxies=_lowercase		,					use_auth_token=_lowercase		,					revision=_lowercase		,					local_files_only=_lowercase		,					)
				return os.path.join(_lowercase		,					_lowercase      )


def        __lowercase    (  UpperCAmelCase__		,					UpperCAmelCase__		,					UpperCAmelCase__ = None		,					UpperCAmelCase__ = None		,					UpperCAmelCase__ = False		,					UpperCAmelCase__ = False		,					UpperCAmelCase__ = None		,					UpperCAmelCase__ = None		,					UpperCAmelCase__ = None		,					UpperCAmelCase__ = False		,					**UpperCAmelCase__		,					):

				"""simple docstring"""






				__lowerCAmelCase					=							get_cached_module_file(
				    _lowercase		,					_lowercase		,					cache_dir=_lowercase		,					force_download=_lowercase		,					resume_download=_lowercase		,					proxies=_lowercase		,					use_auth_token=_lowercase		,					revision=_lowercase		,					local_files_only=_lowercase		,					)
				return get_class_in_module(_lowercase		,					final_module.replace('.py'		,					''      )      )









from typing import TYPE_CHECKING

from ...utils import OptionalDependencyNotAvailable, _LazyModule, is_torch_available


lowerCamelCase      				=     {
    '''configuration_lilt''': ['''LILT_PRETRAINED_CONFIG_ARCHIVE_MAP''', '''LiltConfig'''],
}

try:
		if not is_torch_available():
				raise OptionalDependencyNotAvailable()
except OptionalDependencyNotAvailable:
		pass
else:
		lowerCamelCase      				=     [
		    '''LILT_PRETRAINED_MODEL_ARCHIVE_LIST''',
		    '''LiltForQuestionAnswering''',
		    '''LiltForSequenceClassification''',
		    '''LiltForTokenClassification''',
		    '''LiltModel''',
		    '''LiltPreTrainedModel''',
		]

if TYPE_CHECKING:
		from .configuration_lilt import LILT_PRETRAINED_CONFIG_ARCHIVE_MAP, LiltConfig

		try:
				if not is_torch_available():
						raise OptionalDependencyNotAvailable()
		except OptionalDependencyNotAvailable:
				pass
		else:
				from .modeling_lilt import (
				    LILT_PRETRAINED_MODEL_ARCHIVE_LIST,
				    LiltForQuestionAnswering,
				    LiltForSequenceClassification,
				    LiltForTokenClassification,
				    LiltModel,
				    LiltPreTrainedModel,
				)

else:
		import sys

		lowerCamelCase      				=     _LazyModule(__name__, globals()['''__file__'''], _import_structure, module_spec=__spec__)






