Spaces:
Sleeping
Sleeping
| # coding: utf-8 | |
| # Copyright (c) 2025 inclusionAI. | |
| import logging | |
| import os | |
| import sys | |
| import re | |
| import subprocess | |
| from setuptools import setup, find_packages | |
| from setuptools.command.sdist import sdist | |
| from setuptools.command.install import install | |
| from setuptools.dist import Distribution | |
| from aworld.version_gen import __version__ | |
| logger = logging.getLogger("setup") | |
| version_template = """ | |
| # auto generated | |
| class VersionInfo(object): | |
| @property | |
| def build_date(self): | |
| return "{BUILD_DATE}" | |
| @property | |
| def version(self): | |
| return "{BUILD_VERSION}" | |
| @property | |
| def build_user(self): | |
| return "{BUILD_USER}" | |
| """ | |
| def check_output(cmd): | |
| import subprocess | |
| output = subprocess.check_output(cmd) | |
| return output.decode("utf-8") | |
| def get_build_date(): | |
| import datetime | |
| import time | |
| ts = time.time() | |
| return datetime.datetime.fromtimestamp(ts).strftime("%Y-%m-%d %H:%M:%S") | |
| def build_version_template(): | |
| import getpass | |
| return version_template.format( | |
| BUILD_USER=getpass.getuser(), | |
| BUILD_VERSION=__version__, | |
| BUILD_DATE=get_build_date(), | |
| ) | |
| def call_process(cmd, raise_on_error=True, logging=True): | |
| if isinstance(cmd, str): | |
| shell = True | |
| else: | |
| shell = False # cmd should be list of args | |
| try: | |
| subprocess.check_call(cmd, shell=shell, timeout=60) | |
| except subprocess.CalledProcessError as e: | |
| if raise_on_error: | |
| raise e | |
| logger.error(f"Fail to execute {cmd}, {e}") | |
| return e.returncode | |
| if logging: | |
| logger.info(f"Successfully execute: {cmd}") | |
| return 0 | |
| class AWorldPackage(sdist): | |
| def run(self): | |
| from aworld.version_gen import generate_version_info | |
| home = os.path.join(os.path.dirname(__file__), "aworld") | |
| with open(os.path.join(home, "version.py"), "w") as f: | |
| version_info = build_version_template() | |
| f.write(version_info) | |
| generate_version_info(scenario="AWORLD_SDIST") | |
| sdist.run(self) | |
| class AWorldInstaller(install): | |
| EXTRA_ENV = "AWORLD_EXTRA" | |
| BASE = "framework" | |
| BASE_OPT = "optional" | |
| def __init__(self, *args, **kwargs): | |
| super(AWorldInstaller, self).__init__(*args, **kwargs) | |
| self._requirements = parse_requirements("aworld/requirements.txt") | |
| self._extra = os.getenv(self.EXTRA_ENV) | |
| logger.info(f"{os.getcwd()}: Install AWORLD using extra: {self._extra}") | |
| def run(self): | |
| # 1. build wheel using this setup.py, thus using the right install_requires according to ALPS_EXTRA | |
| # 2. install this wheel into pip | |
| install.run(self) | |
| reqs = self._requirements.get(self.BASE, []) | |
| self._install_reqs(reqs, ignore_error=True) | |
| # install optional requirements here since pip install doesn't ignore requirement error | |
| reqs = self._requirements.get(self.BASE_OPT, []) | |
| self._install_reqs(reqs, ignore_error=True) | |
| def _contains_module(self, module): | |
| if self._extra is None: | |
| return False | |
| modules = [mod.strip() for mod in self._extra.split(",")] | |
| try: | |
| modules.index(module) | |
| return True | |
| except ValueError: | |
| return False | |
| def _install_reqs(reqs, ignore_error=False, no_deps=False): | |
| info = "--no-deps" if no_deps else "" | |
| if ignore_error: | |
| # install requirements one by one | |
| for req in reqs: | |
| try: | |
| cmd = f"{sys.executable} -m pip install {info} {req}" | |
| call_process(cmd) | |
| logger.info(f"Installing optional package {req} have succeeded.") | |
| except: | |
| logger.warning( | |
| f"Installing optional package {req} is failed, Ignored." | |
| ) # ignore | |
| elif reqs: | |
| cmd = f"{sys.executable} -m pip install {info} {' '.join(reqs)}" | |
| call_process(cmd) | |
| logger.info(f"Packages {str(reqs)} have been installed.") | |
| def parse_requirements(req_fname): | |
| requirements = {} | |
| module_name = "unknown" | |
| for line in open(req_fname, "r"): | |
| match = re.match(r"#+\s+\[(\w+)\]\s+#+", line.strip()) | |
| if match: | |
| # the beginning of a module | |
| module_name = match.group(1) | |
| else: | |
| req = line.strip() | |
| if not req or req.startswith("#"): | |
| continue | |
| # it's a requirement, strip trailing comments | |
| pos = req.find("#") | |
| if pos > 0: | |
| req = req[:pos] | |
| req = req.strip() | |
| if module_name not in requirements: | |
| requirements[module_name] = [] | |
| requirements[module_name].append(req) | |
| return requirements | |
| def get_install_requires(extra, requirements): | |
| modules = [AWorldInstaller.BASE] | |
| if extra is None: | |
| # old style of `pip install alps`, install all requirements for compatibility | |
| for mod in requirements: | |
| if mod in [AWorldInstaller.BASE, AWorldInstaller.BASE_OPT]: | |
| continue | |
| modules.append(mod) | |
| else: | |
| for mod in extra.split(","): | |
| mod = mod.strip() | |
| if mod != AWorldInstaller.BASE: | |
| modules.append(mod) | |
| install_reqs = [] | |
| for mod in modules: | |
| install_reqs.extend(requirements.get(mod, [])) | |
| return install_reqs | |
| def get_python_requires(): | |
| return ">=3.11" | |
| class BinaryDistribution(Distribution): | |
| """This class is needed in order to create OS specific wheels.""" | |
| def has_ext_modules(): | |
| return True | |
| requirements = parse_requirements("aworld/requirements.txt") | |
| extra = os.getenv(AWorldInstaller.EXTRA_ENV, None) | |
| setup( | |
| name="aworld", | |
| version=__version__, | |
| description="Ant Agent Package", | |
| url="https://github.com/inclusionAI/AWorld", | |
| author="Ant AI", | |
| author_email="", | |
| long_description="", | |
| long_description_content_type="text/markdown", | |
| packages=find_packages( | |
| where=".", | |
| exclude=["tests", "tests.*", "*.tests", "*.tests.*", "*.test", "*.test.*"], | |
| ), | |
| package_data={ | |
| "aworld": [ | |
| "virtual_environments/browsers/script/*.js", | |
| "dataset/gaia/gaia.npy", | |
| "requirements.txt", | |
| "config/*.yaml", | |
| "config/*.json", | |
| "config/*.tiktoken", | |
| "web/templates/*.html", | |
| ] | |
| }, | |
| license="MIT", | |
| platforms=["any"], | |
| keywords=["multi-agent", "agent", "environment", "tool", "sandbox"], | |
| cmdclass={ | |
| "sdist": AWorldPackage, | |
| "install": AWorldInstaller, | |
| }, | |
| install_requires=get_install_requires(extra, requirements), | |
| python_requires=get_python_requires(), | |
| classifiers=[ | |
| "Development Status :: 5 - Production/Stable", | |
| # Indicate who your project is intended for | |
| "Intended Audience :: Developers", | |
| "Topic :: Software Development :: Build Tools", | |
| "Programming Language :: Python :: 3.11", | |
| "Programming Language :: Python :: 3.12", | |
| ], | |
| entry_points={ | |
| "console_scripts": [ | |
| "aworld = aworld.__main__:main", | |
| ] | |
| }, | |
| ) | |