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:
Eduardo Chiarotti
2024-10-25 10:33:21 -03:00
committed by GitHub
parent 201e652fa2
commit 4589d6fe9d
5 changed files with 35 additions and 29 deletions

View File

@@ -28,6 +28,7 @@ dependencies = [
"uv>=0.4.25",
"tomli-w>=1.1.0",
"chromadb>=0.4.24",
"tomli>=2.0.2",
]
[project.urls]

View File

@@ -1,10 +1,9 @@
import subprocess
import click
import tomllib
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:
@@ -15,10 +14,9 @@ def run_crew() -> None:
crewai_version = get_crewai_version()
min_required_version = "0.71.0"
with open("pyproject.toml", "rb") as f:
data = tomllib.load(f)
pyproject_data = read_toml()
if data.get("tool", {}).get("poetry") and (
if pyproject_data.get("tool", {}).get("poetry") and (
version.parse(crewai_version) < version.parse(min_required_version)
):
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(e.output, err=True, nl=True)
with open("pyproject.toml", "rb") as f:
data = tomllib.load(f)
if data.get("tool", {}).get("poetry"):
if pyproject_data.get("tool", {}).get("poetry"):
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.",
fg="yellow",

View File

@@ -2,7 +2,8 @@ import os
import shutil
import tomli_w
import tomllib
from crewai.cli.utils import read_toml
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.
When the time comes that uv supports the new format, this function will be deprecated.
"""
poetry_data = {}
# Read the input pyproject.toml
with open(input_file, "rb") as f:
pyproject = tomllib.load(f)
pyproject_data = read_toml()
# Initialize the new project structure
new_pyproject = {
@@ -30,30 +30,30 @@ def migrate_pyproject(input_file, output_file):
}
# Migrate project metadata
if "tool" in pyproject and "poetry" in pyproject["tool"]:
poetry = pyproject["tool"]["poetry"]
new_pyproject["project"]["name"] = poetry.get("name")
new_pyproject["project"]["version"] = poetry.get("version")
new_pyproject["project"]["description"] = poetry.get("description")
if "tool" in pyproject_data and "poetry" in pyproject_data["tool"]:
poetry_data = pyproject_data["tool"]["poetry"]
new_pyproject["project"]["name"] = poetry_data.get("name")
new_pyproject["project"]["version"] = poetry_data.get("version")
new_pyproject["project"]["description"] = poetry_data.get("description")
new_pyproject["project"]["authors"] = [
{
"name": author.split("<")[0].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:
# 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
if "dependencies" in new_pyproject["project"]:
# If dependencies are already in the new format, keep them as is
pass
elif "dependencies" in poetry:
elif poetry_data and "dependencies" in poetry_data:
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
extras = ",".join(version.get("extras", []))
new_dep = f"{dep}[{extras}]"
@@ -67,10 +67,10 @@ def migrate_pyproject(input_file, output_file):
new_pyproject["project"]["dependencies"].append(new_dep)
# Migrate or copy scripts
if "scripts" in poetry:
new_pyproject["project"]["scripts"] = poetry["scripts"]
elif "scripts" in pyproject.get("project", {}):
new_pyproject["project"]["scripts"] = pyproject["project"]["scripts"]
if poetry_data and "scripts" in poetry_data:
new_pyproject["project"]["scripts"] = poetry_data["scripts"]
elif pyproject_data.get("project", {}) and "scripts" in pyproject_data["project"]:
new_pyproject["project"]["scripts"] = pyproject_data["project"]["scripts"]
else:
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"
# Migrate optional dependencies
if "extras" in poetry:
new_pyproject["project"]["optional-dependencies"] = poetry["extras"]
if poetry_data and "extras" in poetry_data:
new_pyproject["project"]["optional-dependencies"] = poetry_data["extras"]
# Backup the old pyproject.toml
backup_file = "pyproject-old.toml"

View File

@@ -6,6 +6,7 @@ from functools import reduce
from typing import Any, Dict, List
import click
import tomli
from rich.console import Console
from crewai.cli.authentication.utils import TokenManager
@@ -54,6 +55,13 @@ def simple_toml_parser(content):
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):
if sys.version_info >= (3, 11):
return tomllib.loads(content)

2
uv.lock generated
View File

@@ -625,6 +625,7 @@ dependencies = [
{ name = "python-dotenv" },
{ name = "pyvis" },
{ name = "regex" },
{ name = "tomli" },
{ name = "tomli-w" },
{ name = "uv" },
]
@@ -679,6 +680,7 @@ requires-dist = [
{ name = "python-dotenv", specifier = ">=1.0.0" },
{ name = "pyvis", specifier = ">=0.3.2" },
{ name = "regex", specifier = ">=2024.9.11" },
{ name = "tomli", specifier = ">=2.0.2" },
{ name = "tomli-w", specifier = ">=1.1.0" },
{ name = "uv", specifier = ">=0.4.25" },
]