mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-07-01 05:08:12 +00:00
* Update crewAI CLI with various enhancements and fixes - Updated `create_json_crew.py` to require `crewai[tools]>=1.14.7`. - Enhanced `git.py` with improved repository initialization, including automatic initial commit creation and exclusion patterns for initial commits. - Modified `install_crew.py` to allow error handling during installation with an optional `raise_on_error` parameter. - Expanded `plus_api.py` to include methods for creating and updating crews from ZIP files. - Introduced a new `archive.py` for creating deployable ZIP archives of CrewAI projects, ensuring local artifacts are excluded. - Updated `run_crew.py` to manage JSON crew dependencies and run crews in the project's environment. - Enhanced deployment logic in `main.py` to handle ZIP uploads and improve user feedback during deployment processes. - Added tests for new functionalities and ensured existing tests reflect recent changes in behavior and requirements. * fix(cli): address deploy zip review feedback * fix(cli): sync missing lockfile before deploy * fix(cli): preserve remote deploy on git setup warnings * test(cli): use single deploy main import style * fix(cli): skip project install for json crew sync * fix(cli): load json runner from source checkout * fix(cli): skip json crew sync when locked * fix(cli): address deploy zip review feedback * fix(cli): pass env on zip redeploy * fix(cli): harden json run and zip fallback * fix(cli): validate before deploy lock install * fix(cli): respect poetry lock for json runs * fix(cli): align json zip wrapper detection * fix(deps): bump starlette audit floor * fix(cli): avoid auth retry for deploy exits * fix(cli): update json zip script entrypoints
96 lines
2.9 KiB
Python
96 lines
2.9 KiB
Python
"""CrewAI CLI API client extensions."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
from typing import Any, Literal, cast
|
|
from urllib.parse import urljoin
|
|
|
|
from crewai_core.plus_api import PlusAPI as _CorePlusAPI
|
|
import httpx
|
|
|
|
|
|
HttpMethod = Literal["GET", "POST", "PATCH", "DELETE"]
|
|
|
|
|
|
class PlusAPI(_CorePlusAPI):
|
|
"""CLI API client.
|
|
|
|
The ZIP deployment methods live here as well as in newer crewai-core
|
|
versions so editable CLI installs still work when an older crewai-core is
|
|
present in the runtime environment.
|
|
"""
|
|
|
|
def _make_multipart_request(
|
|
self,
|
|
method: HttpMethod,
|
|
endpoint: str,
|
|
*,
|
|
zip_file_path: str | Path,
|
|
data: dict[str, str] | None = None,
|
|
timeout: float | None = None,
|
|
verify: bool = True,
|
|
) -> httpx.Response:
|
|
"""Send an authenticated multipart request containing a project ZIP."""
|
|
url = urljoin(self.base_url, endpoint)
|
|
headers = dict(cast(dict[str, str], self.headers))
|
|
headers.pop("Content-Type", None)
|
|
path = Path(zip_file_path)
|
|
request_kwargs: dict[str, Any] = {"headers": headers}
|
|
if data is not None:
|
|
request_kwargs["data"] = data
|
|
if timeout is not None:
|
|
request_kwargs["timeout"] = timeout
|
|
|
|
with (
|
|
path.open("rb") as file_handle,
|
|
httpx.Client(trust_env=False, verify=verify) as client,
|
|
):
|
|
files = {
|
|
"zip_file": (path.name, file_handle, "application/zip"),
|
|
}
|
|
return client.request(method, url, files=files, **request_kwargs)
|
|
|
|
def create_crew_from_zip(
|
|
self,
|
|
zip_file_path: str | Path,
|
|
*,
|
|
name: str | None = None,
|
|
env: dict[str, str] | None = None,
|
|
) -> httpx.Response:
|
|
"""Create a crew deployment from a local project ZIP archive."""
|
|
data: dict[str, str] = {}
|
|
if name:
|
|
data["name"] = name
|
|
if env:
|
|
data.update({f"env[{key}]": value for key, value in env.items()})
|
|
return self._make_multipart_request(
|
|
"POST",
|
|
f"{self.CREWS_RESOURCE}/zip",
|
|
zip_file_path=zip_file_path,
|
|
data=data or None,
|
|
timeout=300,
|
|
)
|
|
|
|
def update_crew_from_zip(
|
|
self,
|
|
uuid: str,
|
|
zip_file_path: str | Path,
|
|
*,
|
|
env: dict[str, str] | None = None,
|
|
) -> httpx.Response:
|
|
"""Update an existing crew deployment from a local project ZIP archive."""
|
|
data: dict[str, str] = {}
|
|
if env:
|
|
data.update({f"env[{key}]": value for key, value in env.items()})
|
|
return self._make_multipart_request(
|
|
"POST",
|
|
f"{self.CREWS_RESOURCE}/{uuid}/zip_update",
|
|
zip_file_path=zip_file_path,
|
|
data=data or None,
|
|
timeout=300,
|
|
)
|
|
|
|
|
|
__all__ = ["PlusAPI"]
|