Files
crewAI/lib/cli/src/crewai_cli/plus_api.py
João Moura 53c2284484 Support ZIP deployment fallback and JSON crew project env runs (#6166)
* 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
2026-06-15 18:46:54 -03:00

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"]