mirror of
https://github.com/langchain-ai/langgraph.git
synced 2026-08-17 21:25:46 +02:00
Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
656737009b | ||
|
|
ecdf70a2ab |
@@ -0,0 +1,41 @@
|
||||
# Python
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
*.so
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
|
||||
# Virtual environments
|
||||
venv/
|
||||
env/
|
||||
ENV/
|
||||
|
||||
# Editor
|
||||
.idea/
|
||||
.vscode/
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
# OS specific
|
||||
.DS_Store
|
||||
|
||||
# Testing
|
||||
.pytest_cache/
|
||||
.coverage
|
||||
htmlcov/
|
||||
.tox/
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2025 LangChain, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,24 @@
|
||||
.PHONY: install format lint clean build publish
|
||||
|
||||
install:
|
||||
poetry install
|
||||
|
||||
format:
|
||||
poetry run ruff format langgraph_cli_install tests
|
||||
|
||||
lint:
|
||||
poetry run ruff check langgraph_cli_install tests
|
||||
|
||||
test:
|
||||
poetry run pytest
|
||||
|
||||
clean:
|
||||
rm -rf dist/
|
||||
rm -rf build/
|
||||
rm -rf *.egg-info/
|
||||
|
||||
build: clean
|
||||
poetry build
|
||||
|
||||
publish: build
|
||||
poetry publish
|
||||
@@ -0,0 +1,50 @@
|
||||
# LangGraph CLI Installer
|
||||
|
||||
A simple installer for the LangGraph CLI that uses `uv` to create an isolated environment.
|
||||
|
||||
## Why?
|
||||
|
||||
This lightweight installer creates an isolated installation of LangGraph CLI without worrying about Python environment conflicts or dependencies. It uses [uv](https://github.com/astral-sh/uv) to create a standalone environment with LangGraph CLI.
|
||||
|
||||
Key benefits:
|
||||
- Prevents conflicts with other Python packages
|
||||
- No knowledge of virtual environments needed
|
||||
- Adds to your PATH automatically
|
||||
- Installs the latest version of LangGraph CLI
|
||||
|
||||
## Quick Install
|
||||
|
||||
Simply run:
|
||||
|
||||
```bash
|
||||
pip install langgraph-cli-install && langgraph-cli-install
|
||||
```
|
||||
|
||||
This will:
|
||||
1. Install the uv package if not already installed
|
||||
2. Create an isolated environment with the latest LangGraph CLI
|
||||
3. Add the CLI to your PATH automatically
|
||||
|
||||
After installation, you can run `langgraph --help` to get started.
|
||||
|
||||
## How It Works
|
||||
|
||||
This installer is similar to [aider-install](https://github.com/paul-gauthier/aider/blob/main/aider_install/main.py). It:
|
||||
|
||||
1. Uses the `uv` Python installer to create an isolated environment
|
||||
2. Installs the latest `langgraph-cli` in that environment
|
||||
3. Adds the installed binary to your PATH
|
||||
|
||||
This approach dramatically reduces installation issues caused by Python environment conflicts.
|
||||
|
||||
## Manual Installation
|
||||
|
||||
If you prefer not to use this installer, you can install LangGraph CLI directly:
|
||||
|
||||
```bash
|
||||
pip install langgraph-cli
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
@@ -0,0 +1,7 @@
|
||||
"""LangGraph CLI Installer package."""
|
||||
|
||||
__version__ = "0.1.0"
|
||||
|
||||
from .main import main
|
||||
|
||||
__all__ = ["main"]
|
||||
@@ -0,0 +1,109 @@
|
||||
"""LangGraph CLI Installation Script.
|
||||
|
||||
Main entry point for installing langgraph-cli in an isolated environment.
|
||||
This script uses uv to create an isolated installation of langgraph-cli.
|
||||
"""
|
||||
|
||||
import platform
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
import uv
|
||||
|
||||
|
||||
def main():
|
||||
"""Install langgraph-cli using uv in an isolated environment."""
|
||||
print("Installing LangGraph CLI...")
|
||||
|
||||
try:
|
||||
uv_bin = uv.find_uv_bin()
|
||||
|
||||
# Get best Python version for installation (prefer 3.12 if available)
|
||||
python_version = get_latest_python_version()
|
||||
|
||||
# Create an isolated environment with langgraph-cli
|
||||
print(f"Creating isolated environment using {python_version}...")
|
||||
subprocess.check_call(
|
||||
[
|
||||
uv_bin,
|
||||
"tool",
|
||||
"install",
|
||||
"--force",
|
||||
"--python",
|
||||
python_version,
|
||||
"langgraph-cli@latest",
|
||||
]
|
||||
)
|
||||
|
||||
# Update PATH so the tool is available
|
||||
subprocess.check_call([uv_bin, "tool", "update-shell"])
|
||||
|
||||
# Show install location and help
|
||||
show_success_message(uv_bin)
|
||||
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"\nFailed to install langgraph-cli: {e}")
|
||||
sys.exit(1)
|
||||
except Exception as e:
|
||||
print(f"\nAn error occurred: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def get_latest_python_version() -> str:
|
||||
"""Get the latest compatible Python version for installation."""
|
||||
# Try to use Python 3.13 if possible, otherwise fall back to the current version
|
||||
target_version = "3.13"
|
||||
try:
|
||||
# Check if this version is available through uv
|
||||
uv_bin = uv.find_uv_bin()
|
||||
result = subprocess.run(
|
||||
[uv_bin, "python", "list"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=False,
|
||||
)
|
||||
if target_version in result.stdout:
|
||||
return f"python{target_version}"
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Fall back to current version
|
||||
major, minor = sys.version_info.major, sys.version_info.minor
|
||||
return f"python{major}.{minor}"
|
||||
|
||||
|
||||
def show_success_message(uv_bin):
|
||||
"""Show success message and installation details."""
|
||||
# Get installation path
|
||||
result = subprocess.run(
|
||||
[uv_bin, "tool", "list"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=True,
|
||||
)
|
||||
|
||||
install_path = None
|
||||
for line in result.stdout.splitlines():
|
||||
if "langgraph-cli" in line:
|
||||
parts = line.strip().split()
|
||||
if len(parts) >= 2:
|
||||
install_path = parts[1]
|
||||
break
|
||||
|
||||
# Success message
|
||||
print("\n🎉 LangGraph CLI has been successfully installed!\n")
|
||||
print("You can now use it by running:")
|
||||
print(" langgraph --help")
|
||||
|
||||
if install_path:
|
||||
print(f"\nInstalled at: {install_path}")
|
||||
|
||||
# Provide hint about shell restart if needed
|
||||
if platform.system() != "Windows":
|
||||
print("\nNote: You may need to restart your terminal or run:")
|
||||
print(" source ~/.bashrc # or ~/.zshrc depending on your shell")
|
||||
print("to ensure the langgraph command is available in your PATH.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Generated
+44
@@ -0,0 +1,44 @@
|
||||
# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand.
|
||||
|
||||
[[package]]
|
||||
name = "packaging"
|
||||
version = "23.2"
|
||||
description = "Core utilities for Python packages"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"},
|
||||
{file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uv"
|
||||
version = "0.1.45"
|
||||
description = "An extremely fast Python package installer and resolver, written in Rust."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "uv-0.1.45-py3-none-linux_armv6l.whl", hash = "sha256:088af576fb0e0462cd5f718d03fb1a9f16ce5ae61fdb2a9d3ea938fc826cecc1"},
|
||||
{file = "uv-0.1.45-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b94180009264f3f7ee74250f8e4f99c8cb0cb3633e3a9c9c66cdef3eb69be575"},
|
||||
{file = "uv-0.1.45-py3-none-macosx_11_0_arm64.whl", hash = "sha256:4e5d55f0f8b6ae416c72d78106e224c8e8338356da21ddebecc7b1723de80924"},
|
||||
{file = "uv-0.1.45-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:7fdb235aaf420fa8ac9009999b1654a23540f03e25c35094543c2f48d7c41aef"},
|
||||
{file = "uv-0.1.45-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:de81501c0b03160d0944906d1a713f108258360e20c58385974acb7253b56166"},
|
||||
{file = "uv-0.1.45-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:346aa2d0a4ad3c0c3f7852c1edf5e5a8e5d2ef34c7474e9089877291c2da979c"},
|
||||
{file = "uv-0.1.45-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:a601eed14d484d36d421e4208911a56aaf758ea6c385ef8edf8ad9f8ead57ce1"},
|
||||
{file = "uv-0.1.45-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2ca2d5a5e06c5f71c7b213e14fa59129e63b77de3ffbcf84ecc98d647d73a821"},
|
||||
{file = "uv-0.1.45-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:90b68c80dddebeca69b26a2af1e2e683804bcf2b5f22d107af03d9156d6218c6"},
|
||||
{file = "uv-0.1.45-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cd7f2f64fdded940342dc37234c11ae3508222c3c9b6b0eac5879dcd586010fa"},
|
||||
{file = "uv-0.1.45-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:a39141e179fea043151a165c9155031e7976b0e4b076c0c33a45b58a420134e0"},
|
||||
{file = "uv-0.1.45-py3-none-musllinux_1_1_armv7l.whl", hash = "sha256:68718add6ee2cef2816f9bf8a1dbf2d8cf63d98ddf45840f340029f65a49fd89"},
|
||||
{file = "uv-0.1.45-py3-none-musllinux_1_1_i686.whl", hash = "sha256:110e0f45ddb2fe832ce50b0308be90e5439e0c02d3ffe042feeb3f759811f31f"},
|
||||
{file = "uv-0.1.45-py3-none-musllinux_1_1_ppc64le.whl", hash = "sha256:0f6cfe885f109bacc055edd5df2c837616ae2238b9324a9d37835a96b204ab2f"},
|
||||
{file = "uv-0.1.45-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:87e77d25e8f358c0d5de1983497ee4cf4cea8fc73373d1ef1063533352db2f89"},
|
||||
{file = "uv-0.1.45-py3-none-win32.whl", hash = "sha256:ddb93620c9e01fa83573c2648df4bee3fa548ca940de51c8a2c3566a23a0c776"},
|
||||
{file = "uv-0.1.45-py3-none-win_amd64.whl", hash = "sha256:8e2eeea4eec0e09f7d67378152428b5308dba8b33990d045d7a31d19bf18ca1f"},
|
||||
{file = "uv-0.1.45.tar.gz", hash = "sha256:40fab956bc7af50dfa4bda14e5871528f57603eb9bf8595eb3144aace0ed8c47"},
|
||||
]
|
||||
|
||||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "^3.8.0,<4.0"
|
||||
content-hash = "ac29a6587488fe83583561554cb37b0812f4609cf34fedc4afae8df804db0d73"
|
||||
@@ -0,0 +1,36 @@
|
||||
[tool.poetry]
|
||||
name = "langgraph-cli-install"
|
||||
version = "0.0.1-rc1"
|
||||
description = "Simple installer for langgraph-cli"
|
||||
authors = []
|
||||
license = "MIT"
|
||||
readme = "README.md"
|
||||
repository = "https://www.github.com/langchain-ai/langgraph"
|
||||
packages = [{ include = "langgraph_cli_install" }]
|
||||
|
||||
[tool.poetry.scripts]
|
||||
langgraph-cli-install = "langgraph_cli_install.main:main"
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.9.0,<4.0"
|
||||
packaging = ">=23.0"
|
||||
uv = ">=0.6.0"
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core"]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
|
||||
[tool.ruff]
|
||||
lint.select = [
|
||||
# pycodestyle
|
||||
"E",
|
||||
# Pyflakes
|
||||
"F",
|
||||
# pyupgrade
|
||||
"UP",
|
||||
# flake8-bugbear
|
||||
"B",
|
||||
# isort
|
||||
"I",
|
||||
]
|
||||
lint.ignore = ["E501", "B008"]
|
||||
@@ -0,0 +1,36 @@
|
||||
"""Setup script for the langgraph-cli-install package."""
|
||||
|
||||
from setuptools import find_packages, setup
|
||||
|
||||
if __name__ == "__main__":
|
||||
setup(
|
||||
name="langgraph-cli-install",
|
||||
version="0.1.0",
|
||||
description="Simple installer for langgraph-cli",
|
||||
author="",
|
||||
author_email="",
|
||||
license="MIT",
|
||||
packages=find_packages(),
|
||||
include_package_data=True,
|
||||
entry_points={
|
||||
"console_scripts": [
|
||||
"langgraph-cli-install=langgraph_cli_install.main:main",
|
||||
],
|
||||
},
|
||||
python_requires=">=3.8",
|
||||
install_requires=[
|
||||
"uv>=0.1.24",
|
||||
"packaging>=23.0",
|
||||
],
|
||||
classifiers=[
|
||||
"Development Status :: 4 - Beta",
|
||||
"Intended Audience :: Developers",
|
||||
"License :: OSI Approved :: MIT License",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Programming Language :: Python :: 3.8",
|
||||
"Programming Language :: Python :: 3.9",
|
||||
"Programming Language :: Python :: 3.10",
|
||||
"Programming Language :: Python :: 3.11",
|
||||
"Programming Language :: Python :: 3.12",
|
||||
],
|
||||
)
|
||||
@@ -0,0 +1 @@
|
||||
"""Test package for langgraph-cli-install."""
|
||||
@@ -0,0 +1,50 @@
|
||||
"""Tests for the main module."""
|
||||
|
||||
import sys
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from langgraph_cli_install.main import get_latest_python_version, main
|
||||
|
||||
|
||||
def test_get_latest_python_version():
|
||||
"""Test that the get_latest_python_version function returns a string."""
|
||||
with patch("subprocess.run") as mock_run:
|
||||
mock_result = MagicMock()
|
||||
mock_result.stdout = "python3.12"
|
||||
mock_run.return_value = mock_result
|
||||
|
||||
with patch("uv.find_uv_bin", return_value="/path/to/uv"):
|
||||
version = get_latest_python_version()
|
||||
assert isinstance(version, str)
|
||||
assert "python" in version
|
||||
|
||||
|
||||
def test_get_latest_python_version_fallback():
|
||||
"""Test fallback to current version when 3.12 is not available."""
|
||||
with patch("subprocess.run") as mock_run:
|
||||
mock_result = MagicMock()
|
||||
mock_result.stdout = "python3.8" # No 3.12 here
|
||||
mock_run.return_value = mock_result
|
||||
|
||||
with patch("uv.find_uv_bin", return_value="/path/to/uv"):
|
||||
# Mock sys.version_info
|
||||
old_version_info = sys.version_info
|
||||
sys.version_info = MagicMock()
|
||||
sys.version_info.major = 3
|
||||
sys.version_info.minor = 9
|
||||
|
||||
try:
|
||||
version = get_latest_python_version()
|
||||
assert isinstance(version, str)
|
||||
assert "python3.9" in version
|
||||
finally:
|
||||
# Restore original version_info
|
||||
sys.version_info = old_version_info
|
||||
|
||||
|
||||
def test_main_exception():
|
||||
"""Test main function handles exceptions."""
|
||||
with patch("uv.find_uv_bin", side_effect=Exception("Test error")):
|
||||
with patch("sys.exit") as mock_exit:
|
||||
main()
|
||||
mock_exit.assert_called_once_with(1)
|
||||
@@ -0,0 +1,8 @@
|
||||
"""Test that the version is defined."""
|
||||
|
||||
import langgraph_cli_install
|
||||
|
||||
|
||||
def test_version():
|
||||
"""Test that the version is defined."""
|
||||
assert langgraph_cli_install.__version__ is not None
|
||||
@@ -198,7 +198,7 @@ class CorsConfig(TypedDict, total=False):
|
||||
allow_origin_regex: str
|
||||
"""Optional. A regex pattern for matching allowed origins, used if you have dynamic subdomains.
|
||||
|
||||
Example: "^https://.*\.mycompany\.com$"
|
||||
Example: "^https://\\.*\\.mycompany\\.com$"
|
||||
"""
|
||||
expose_headers: list[str]
|
||||
"""Optional. List of headers that browsers are allowed to read from the response in cross-origin contexts."""
|
||||
|
||||
Reference in New Issue
Block a user