Add additional env info

This commit is contained in:
William Fu-Hinthorn
2023-07-13 13:17:43 -07:00
parent a28ea4303c
commit fa8a97a2be
2 changed files with 98 additions and 47 deletions
+35 -42
View File
@@ -6,12 +6,11 @@ import shutil
import subprocess
from contextlib import contextmanager
from pathlib import Path
from subprocess import CalledProcessError
from typing import Dict, Generator, List, Mapping, Optional, Union, cast
import requests
from langsmith.utils import get_runtime_environment
from langsmith.utils import (get_docker_compose_command,
get_docker_environment, get_runtime_environment)
logging.basicConfig(level=logging.INFO, format="%(message)s")
logger = logging.getLogger(__name__)
@@ -63,32 +62,6 @@ def pprint_services(services_status: List[Mapping[str, Union[str, List[str]]]])
logger.info("\n".join(service_message))
def get_docker_compose_command() -> List[str]:
"""Get the correct docker compose command for this system."""
try:
subprocess.check_call(
["docker", "compose", "--version"],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
)
return ["docker", "compose"]
except (CalledProcessError, FileNotFoundError):
try:
subprocess.check_call(
["docker-compose", "--version"],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
)
return ["docker-compose"]
except (CalledProcessError, FileNotFoundError):
raise ValueError(
"Neither 'docker compose' nor 'docker-compose'"
" commands are available. Please install the Docker"
" server following the instructions for your operating"
" system at https://docs.docker.com/engine/install/"
)
def get_ngrok_url(auth_token: Optional[str]) -> str:
"""Get the ngrok URL for the LangSmith server."""
ngrok_url = "http://localhost:4040/api/tunnels"
@@ -286,18 +259,27 @@ class LangSmithCommand:
else:
self._start_local(dev=dev)
def stop(self) -> None:
def stop(self, clear_volumes: bool = False) -> None:
"""Stop the LangSmith server."""
subprocess.run(
[
*self.docker_compose_command,
"-f",
str(self.docker_compose_file),
"-f",
str(self.ngrok_path),
"down",
]
)
cmd = [
*self.docker_compose_command,
"-f",
str(self.docker_compose_file),
"-f",
str(self.ngrok_path),
"down",
]
if clear_volumes:
confirm = input(
"You are about to delete all the locally cached LangSmith containers and volumes. "
"This operation cannot be undone. Are you sure? [y/N]"
)
if confirm.lower() != "y":
print("Aborting.")
return
cmd.append("--volumes")
subprocess.run(cmd)
def logs(self) -> None:
"""Print the logs from the LangSmith server."""
@@ -346,8 +328,14 @@ class LangSmithCommand:
def env() -> None:
"""Print the runtime environment information."""
env = get_runtime_environment()
env.update(get_docker_environment())
# calculate the max length of keys
max_key_length = max(len(key) for key in env.keys())
logger.info("LangChain Environment:")
logger.info("\n".join(f"{k}:{v}" for k, v in env.items()))
for k, v in env.items():
logger.info(f"{k:{max_key_length}}: {v}")
def main() -> None:
@@ -395,7 +383,12 @@ def main() -> None:
server_stop_parser = subparsers.add_parser(
"stop", description="Stop the LangSmith server."
)
server_stop_parser.set_defaults(func=lambda args: server_command.stop())
server_stop_parser.add_argument(
"--clear-volumes",
action="store_true",
help="Delete all the locally cached LangSmith containers and volumes.",
)
server_stop_parser.set_defaults(func=lambda args: server_command.stop(clear_volumes=args.clear_volumes))
server_pull_parser = subparsers.add_parser(
"pull", description="Pull the latest LangSmith images."
+63 -5
View File
@@ -1,25 +1,26 @@
"""Generic utility functions."""
import platform
import subprocess
from functools import lru_cache
from typing import Any, Callable, Tuple
from typing import Any, Callable, List, Tuple
from requests import HTTPError, Response
class LangSmithAPIError(Exception):
"""An error occurred while communicating with the LangChain API."""
"""An error occurred while communicating with the LangSmith API."""
class LangSmithUserError(Exception):
"""An error occurred while communicating with the LangChain API."""
"""An error occurred while communicating with the LangSmith API."""
class LangSmithError(Exception):
"""An error occurred while communicating with the LangChain API."""
"""An error occurred while communicating with the LangSmith API."""
class LangSmithConnectionError(Exception):
"""Couldn't connect to the LC+ API."""
"""Couldn't connect to the LangSmith API."""
def xor_args(*arg_groups: Tuple[str, ...]) -> Callable:
@@ -68,3 +69,60 @@ def get_runtime_environment() -> dict:
"runtime": "python",
"runtime_version": platform.python_version(),
}
@lru_cache
def get_docker_compose_command() -> List[str]:
"""Get the correct docker compose command for this system."""
try:
subprocess.check_call(
["docker", "compose", "--version"],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
)
return ["docker", "compose"]
except (subprocess.CalledProcessError, FileNotFoundError):
try:
subprocess.check_call(
["docker-compose", "--version"],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
)
return ["docker-compose"]
except (subprocess.CalledProcessError, FileNotFoundError):
raise ValueError(
"Neither 'docker compose' nor 'docker-compose'"
" commands are available. Please install the Docker"
" server following the instructions for your operating"
" system at https://docs.docker.com/engine/install/"
)
@lru_cache
def get_docker_environment() -> dict:
"""Get information about the environment."""
# Try to get the docker CLI version via subprocess
import subprocess
try:
docker_version = (
subprocess.check_output(["docker", "--version"]).decode("utf-8").strip()
)
except FileNotFoundError:
docker_version = "unknown"
compose_command = get_docker_compose_command()
try:
docker_compose_version = (
subprocess.check_output(["docker-compose", "--version"])
.decode("utf-8")
.strip()
)
except FileNotFoundError:
docker_compose_version = "unknown"
return {
"docker_version": docker_version,
"docker_compose_command": " ".join(compose_command),
"docker_compose_version": docker_compose_version,
}