mirror of
https://github.com/crewAIInc/crewAI.git
synced 2025-12-16 12:28:30 +00:00
feat: add tomli so we can support 3.10 (#1506)
* feat: add tomli so we can support 3.10 * feat: add validation for poetry data
This commit is contained in:
committed by
GitHub
parent
201e652fa2
commit
4589d6fe9d
@@ -28,6 +28,7 @@ dependencies = [
|
|||||||
"uv>=0.4.25",
|
"uv>=0.4.25",
|
||||||
"tomli-w>=1.1.0",
|
"tomli-w>=1.1.0",
|
||||||
"chromadb>=0.4.24",
|
"chromadb>=0.4.24",
|
||||||
|
"tomli>=2.0.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[project.urls]
|
[project.urls]
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
import click
|
import click
|
||||||
import tomllib
|
|
||||||
from packaging import version
|
from packaging import version
|
||||||
|
|
||||||
from crewai.cli.utils import get_crewai_version
|
from crewai.cli.utils import get_crewai_version, read_toml
|
||||||
|
|
||||||
|
|
||||||
def run_crew() -> None:
|
def run_crew() -> None:
|
||||||
@@ -15,10 +14,9 @@ def run_crew() -> None:
|
|||||||
crewai_version = get_crewai_version()
|
crewai_version = get_crewai_version()
|
||||||
min_required_version = "0.71.0"
|
min_required_version = "0.71.0"
|
||||||
|
|
||||||
with open("pyproject.toml", "rb") as f:
|
pyproject_data = read_toml()
|
||||||
data = tomllib.load(f)
|
|
||||||
|
|
||||||
if data.get("tool", {}).get("poetry") and (
|
if pyproject_data.get("tool", {}).get("poetry") and (
|
||||||
version.parse(crewai_version) < version.parse(min_required_version)
|
version.parse(crewai_version) < version.parse(min_required_version)
|
||||||
):
|
):
|
||||||
click.secho(
|
click.secho(
|
||||||
@@ -35,10 +33,7 @@ def run_crew() -> None:
|
|||||||
click.echo(f"An error occurred while running the crew: {e}", err=True)
|
click.echo(f"An error occurred while running the crew: {e}", err=True)
|
||||||
click.echo(e.output, err=True, nl=True)
|
click.echo(e.output, err=True, nl=True)
|
||||||
|
|
||||||
with open("pyproject.toml", "rb") as f:
|
if pyproject_data.get("tool", {}).get("poetry"):
|
||||||
data = tomllib.load(f)
|
|
||||||
|
|
||||||
if data.get("tool", {}).get("poetry"):
|
|
||||||
click.secho(
|
click.secho(
|
||||||
"It's possible that you are using an old version of crewAI that uses poetry, please run `crewai update` to update your pyproject.toml to use uv.",
|
"It's possible that you are using an old version of crewAI that uses poetry, please run `crewai update` to update your pyproject.toml to use uv.",
|
||||||
fg="yellow",
|
fg="yellow",
|
||||||
|
|||||||
@@ -2,7 +2,8 @@ import os
|
|||||||
import shutil
|
import shutil
|
||||||
|
|
||||||
import tomli_w
|
import tomli_w
|
||||||
import tomllib
|
|
||||||
|
from crewai.cli.utils import read_toml
|
||||||
|
|
||||||
|
|
||||||
def update_crew() -> None:
|
def update_crew() -> None:
|
||||||
@@ -18,10 +19,9 @@ def migrate_pyproject(input_file, output_file):
|
|||||||
And it will be used to migrate the pyproject.toml to the new format when uv is used.
|
And it will be used to migrate the pyproject.toml to the new format when uv is used.
|
||||||
When the time comes that uv supports the new format, this function will be deprecated.
|
When the time comes that uv supports the new format, this function will be deprecated.
|
||||||
"""
|
"""
|
||||||
|
poetry_data = {}
|
||||||
# Read the input pyproject.toml
|
# Read the input pyproject.toml
|
||||||
with open(input_file, "rb") as f:
|
pyproject_data = read_toml()
|
||||||
pyproject = tomllib.load(f)
|
|
||||||
|
|
||||||
# Initialize the new project structure
|
# Initialize the new project structure
|
||||||
new_pyproject = {
|
new_pyproject = {
|
||||||
@@ -30,30 +30,30 @@ def migrate_pyproject(input_file, output_file):
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Migrate project metadata
|
# Migrate project metadata
|
||||||
if "tool" in pyproject and "poetry" in pyproject["tool"]:
|
if "tool" in pyproject_data and "poetry" in pyproject_data["tool"]:
|
||||||
poetry = pyproject["tool"]["poetry"]
|
poetry_data = pyproject_data["tool"]["poetry"]
|
||||||
new_pyproject["project"]["name"] = poetry.get("name")
|
new_pyproject["project"]["name"] = poetry_data.get("name")
|
||||||
new_pyproject["project"]["version"] = poetry.get("version")
|
new_pyproject["project"]["version"] = poetry_data.get("version")
|
||||||
new_pyproject["project"]["description"] = poetry.get("description")
|
new_pyproject["project"]["description"] = poetry_data.get("description")
|
||||||
new_pyproject["project"]["authors"] = [
|
new_pyproject["project"]["authors"] = [
|
||||||
{
|
{
|
||||||
"name": author.split("<")[0].strip(),
|
"name": author.split("<")[0].strip(),
|
||||||
"email": author.split("<")[1].strip(">").strip(),
|
"email": author.split("<")[1].strip(">").strip(),
|
||||||
}
|
}
|
||||||
for author in poetry.get("authors", [])
|
for author in poetry_data.get("authors", [])
|
||||||
]
|
]
|
||||||
new_pyproject["project"]["requires-python"] = poetry.get("python")
|
new_pyproject["project"]["requires-python"] = poetry_data.get("python")
|
||||||
else:
|
else:
|
||||||
# If it's already in the new format, just copy the project section
|
# If it's already in the new format, just copy the project section
|
||||||
new_pyproject["project"] = pyproject.get("project", {})
|
new_pyproject["project"] = pyproject_data.get("project", {})
|
||||||
|
|
||||||
# Migrate or copy dependencies
|
# Migrate or copy dependencies
|
||||||
if "dependencies" in new_pyproject["project"]:
|
if "dependencies" in new_pyproject["project"]:
|
||||||
# If dependencies are already in the new format, keep them as is
|
# If dependencies are already in the new format, keep them as is
|
||||||
pass
|
pass
|
||||||
elif "dependencies" in poetry:
|
elif poetry_data and "dependencies" in poetry_data:
|
||||||
new_pyproject["project"]["dependencies"] = []
|
new_pyproject["project"]["dependencies"] = []
|
||||||
for dep, version in poetry["dependencies"].items():
|
for dep, version in poetry_data["dependencies"].items():
|
||||||
if isinstance(version, dict): # Handle extras
|
if isinstance(version, dict): # Handle extras
|
||||||
extras = ",".join(version.get("extras", []))
|
extras = ",".join(version.get("extras", []))
|
||||||
new_dep = f"{dep}[{extras}]"
|
new_dep = f"{dep}[{extras}]"
|
||||||
@@ -67,10 +67,10 @@ def migrate_pyproject(input_file, output_file):
|
|||||||
new_pyproject["project"]["dependencies"].append(new_dep)
|
new_pyproject["project"]["dependencies"].append(new_dep)
|
||||||
|
|
||||||
# Migrate or copy scripts
|
# Migrate or copy scripts
|
||||||
if "scripts" in poetry:
|
if poetry_data and "scripts" in poetry_data:
|
||||||
new_pyproject["project"]["scripts"] = poetry["scripts"]
|
new_pyproject["project"]["scripts"] = poetry_data["scripts"]
|
||||||
elif "scripts" in pyproject.get("project", {}):
|
elif pyproject_data.get("project", {}) and "scripts" in pyproject_data["project"]:
|
||||||
new_pyproject["project"]["scripts"] = pyproject["project"]["scripts"]
|
new_pyproject["project"]["scripts"] = pyproject_data["project"]["scripts"]
|
||||||
else:
|
else:
|
||||||
new_pyproject["project"]["scripts"] = {}
|
new_pyproject["project"]["scripts"] = {}
|
||||||
|
|
||||||
@@ -87,8 +87,8 @@ def migrate_pyproject(input_file, output_file):
|
|||||||
new_pyproject["project"]["scripts"]["run_crew"] = f"{module_name}.main:run"
|
new_pyproject["project"]["scripts"]["run_crew"] = f"{module_name}.main:run"
|
||||||
|
|
||||||
# Migrate optional dependencies
|
# Migrate optional dependencies
|
||||||
if "extras" in poetry:
|
if poetry_data and "extras" in poetry_data:
|
||||||
new_pyproject["project"]["optional-dependencies"] = poetry["extras"]
|
new_pyproject["project"]["optional-dependencies"] = poetry_data["extras"]
|
||||||
|
|
||||||
# Backup the old pyproject.toml
|
# Backup the old pyproject.toml
|
||||||
backup_file = "pyproject-old.toml"
|
backup_file = "pyproject-old.toml"
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ from functools import reduce
|
|||||||
from typing import Any, Dict, List
|
from typing import Any, Dict, List
|
||||||
|
|
||||||
import click
|
import click
|
||||||
|
import tomli
|
||||||
from rich.console import Console
|
from rich.console import Console
|
||||||
|
|
||||||
from crewai.cli.authentication.utils import TokenManager
|
from crewai.cli.authentication.utils import TokenManager
|
||||||
@@ -54,6 +55,13 @@ def simple_toml_parser(content):
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def read_toml(file_path: str = "pyproject.toml"):
|
||||||
|
"""Read the content of a TOML file and return it as a dictionary."""
|
||||||
|
with open(file_path, "rb") as f:
|
||||||
|
toml_dict = tomli.load(f)
|
||||||
|
return toml_dict
|
||||||
|
|
||||||
|
|
||||||
def parse_toml(content):
|
def parse_toml(content):
|
||||||
if sys.version_info >= (3, 11):
|
if sys.version_info >= (3, 11):
|
||||||
return tomllib.loads(content)
|
return tomllib.loads(content)
|
||||||
|
|||||||
2
uv.lock
generated
2
uv.lock
generated
@@ -625,6 +625,7 @@ dependencies = [
|
|||||||
{ name = "python-dotenv" },
|
{ name = "python-dotenv" },
|
||||||
{ name = "pyvis" },
|
{ name = "pyvis" },
|
||||||
{ name = "regex" },
|
{ name = "regex" },
|
||||||
|
{ name = "tomli" },
|
||||||
{ name = "tomli-w" },
|
{ name = "tomli-w" },
|
||||||
{ name = "uv" },
|
{ name = "uv" },
|
||||||
]
|
]
|
||||||
@@ -679,6 +680,7 @@ requires-dist = [
|
|||||||
{ name = "python-dotenv", specifier = ">=1.0.0" },
|
{ name = "python-dotenv", specifier = ">=1.0.0" },
|
||||||
{ name = "pyvis", specifier = ">=0.3.2" },
|
{ name = "pyvis", specifier = ">=0.3.2" },
|
||||||
{ name = "regex", specifier = ">=2024.9.11" },
|
{ name = "regex", specifier = ">=2024.9.11" },
|
||||||
|
{ name = "tomli", specifier = ">=2.0.2" },
|
||||||
{ name = "tomli-w", specifier = ">=1.1.0" },
|
{ name = "tomli-w", specifier = ">=1.1.0" },
|
||||||
{ name = "uv", specifier = ">=0.4.25" },
|
{ name = "uv", specifier = ">=0.4.25" },
|
||||||
]
|
]
|
||||||
|
|||||||
Reference in New Issue
Block a user