Skip to content

Commit 8b7060e

Browse files
authored
added file to langchain folder
1 parent 0e1f17d commit 8b7060e

4 files changed

Lines changed: 3857 additions & 0 deletions

File tree

langchain/env_utils.py

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
# env_utils.py
2+
import os
3+
from dotenv import dotenv_values
4+
5+
def summarize_value(value: str) -> str:
6+
"""Return masked form: ****last4 or boolean string."""
7+
lower = value.lower()
8+
if lower in ("true", "false"):
9+
return lower
10+
return "****" + value[-4:] if len(value) > 4 else "****" + value
11+
12+
def doublecheck_env(file_path: str):
13+
"""Check environment variables against a .env file and print summaries."""
14+
if not os.path.exists(file_path):
15+
print(f"Did not find file {file_path}.")
16+
print("This is used to double check the key settings for the notebook.")
17+
print("This is just a check and is not required.\n")
18+
return
19+
20+
parsed = dotenv_values(file_path)
21+
for key in parsed.keys():
22+
current = os.getenv(key)
23+
if current is not None:
24+
print(f"{key}={summarize_value(current)}")
25+
else:
26+
print(f"{key}=<not set>")
27+
28+
29+
30+
31+
# ========== utility to check packages and python based on pyproject.toml =====================================
32+
33+
# Requires: pip install packaging
34+
import sys, tomllib
35+
from pathlib import Path
36+
from importlib import metadata
37+
from packaging.requirements import Requirement
38+
from packaging.specifiers import SpecifierSet
39+
from packaging.version import Version
40+
41+
def _fmt_row(cols, widths):
42+
return " | ".join(str(c).ljust(w) for c, w in zip(cols, widths))
43+
44+
def doublecheck_pkgs(pyproject_path="pyproject.toml", verbose=False):
45+
p = Path(pyproject_path)
46+
if not p.exists():
47+
print(f"ERROR: {pyproject_path} not found.")
48+
return None
49+
50+
# Load pyproject + python requirement
51+
with p.open("rb") as f:
52+
data = tomllib.load(f)
53+
project = data.get("project", {})
54+
python_spec_str = project.get("requires-python") or ">=3.11"
55+
56+
py_ver = Version(f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}")
57+
py_ok = py_ver in SpecifierSet(python_spec_str)
58+
59+
# Load deps (PEP 621)
60+
deps = project.get("dependencies", [])
61+
if not deps:
62+
if verbose or not py_ok:
63+
print("No [project].dependencies found in pyproject.toml.")
64+
print(f"Python {py_ver} {'satisfies' if py_ok else 'DOES NOT satisfy'} requires-python: {python_spec_str}")
65+
print(f"Executable: {sys.executable}")
66+
return None
67+
68+
# Evaluate deps
69+
results = []
70+
problems = []
71+
for dep in deps:
72+
try:
73+
req = Requirement(dep)
74+
name = req.name
75+
spec = str(req.specifier) if req.specifier else "(any)"
76+
except Exception:
77+
name, spec = dep, "(unparsed)"
78+
79+
rec = {"package": name, "required": spec, "installed": "-", "path": "-", "status": "❌ Missing"}
80+
81+
try:
82+
installed_ver = metadata.version(name)
83+
rec["installed"] = installed_ver
84+
try:
85+
dist = metadata.distribution(name)
86+
rec["path"] = str(dist.locate_file(""))
87+
except Exception:
88+
rec["path"] = "(unknown)"
89+
90+
if spec not in ("(any)", "(unparsed)") and any(op in spec for op in "<>="):
91+
sset = SpecifierSet(spec)
92+
if Version(installed_ver) in sset:
93+
rec["status"] = "✅ OK"
94+
else:
95+
rec["status"] = "⚠️ Version mismatch"
96+
else:
97+
rec["status"] = "✅ OK"
98+
99+
except metadata.PackageNotFoundError:
100+
# keep defaults: installed "-", status "❌ Missing"
101+
pass
102+
103+
results.append(rec)
104+
if rec["status"] != "✅ OK":
105+
problems.append(rec)
106+
107+
should_print = verbose or (not py_ok) or bool(problems)
108+
if should_print:
109+
# Python status
110+
print(f"Python {py_ver} {'satisfies' if py_ok else 'DOES NOT satisfy'} requires-python: {python_spec_str}")
111+
112+
# Table (no hints column)
113+
headers = ["package", "required", "installed", "status", "path"]
114+
def short_path(s, maxlen=80):
115+
s = str(s)
116+
return s if len(s) <= maxlen else ("…" + s[-(maxlen-1):])
117+
rows = [[r["package"], r["required"], r["installed"], r["status"], short_path(r["path"])] for r in results]
118+
widths = [max(len(h), *(len(str(row[i])) for row in rows)) for i, h in enumerate(headers)]
119+
print(_fmt_row(headers, widths))
120+
print(_fmt_row(["-"*w for w in widths], widths))
121+
for row in rows:
122+
print(_fmt_row(row, widths))
123+
124+
# Summarize issues without prescribing a tool
125+
if problems:
126+
print("\nIssues detected:")
127+
for r in problems:
128+
print(f"- {r['package']}: {r['status']} (required {r['required']}, installed {r['installed']}, path {r['path']})")
129+
130+
if verbose or problems or not py_ok:
131+
print("\nEnvironment:")
132+
print(f"- Executable: {sys.executable}")
133+
134+
return None

langchain/pyproject.toml

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
[project]
2+
# Only needed so uv/pip recognizes it as a project
3+
name = "notebooks-to-explore"
4+
version = "0.0.0"
5+
description = "A collection of tutorial notebooks"
6+
requires-python = ">=3.11,<3.14"
7+
8+
# Dependencies you need in the notebooks
9+
dependencies = [
10+
"langgraph>=1.0.0",
11+
"langchain>=1.0.0",
12+
"langchain-core>=1.0.0",
13+
"langchain-openai>=1.0.0",
14+
"langchain-anthropic>=1.0.0",
15+
"langchain-community>=0.4",
16+
"jupyter>=1.0.0",
17+
"langgraph-cli[inmem]>=0.4.0",
18+
"langchain-mcp-adapters",
19+
]
20+
21+
[project.optional-dependencies]
22+
# Extra tools for development
23+
dev = [
24+
"nbdime>=4.0.2",
25+
"ruff>=0.6.1",
26+
"mypy>=1.11.1"
27+
]
28+
29+
[tool.ruff]
30+
# What to check
31+
lint.select = [
32+
"E", # pycodestyle
33+
"F", # pyflakes
34+
"I", # isort
35+
"D", # pydocstyle
36+
"D401", # docstring first line imperative
37+
"UP", # pyupgrade
38+
]
39+
40+
# Rules to ignore
41+
lint.ignore = [
42+
"T201", # allow print()
43+
"UP006", # keep using typing.List etc.
44+
"UP007", # allow Union[X, Y]
45+
"UP035", # ignore Self type suggestion
46+
"D417", # don't require param docs
47+
"E501", # ignore line length
48+
"D101", # ignore docstring for these labs
49+
"D103", # ignore docstring for these labs
50+
"D202", # ignore extra space after docstring requirement
51+
]
52+
53+
[tool.ruff.lint.per-file-ignores]
54+
"tests/*" = ["D", "UP"]
55+
56+
[tool.ruff.lint.pydocstyle]
57+
convention = "google"
58+

langchain/requirements.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
langgraph>=1.0.0
2+
langchain>=1.0.0
3+
langchain-openai>=1.0.0
4+
langchain-anthropic>=1.0.0
5+
langchain-community>=0.4.0
6+
jupyter>=1.0.0
7+
langgraph-cli[inmem]>=0.4.0
8+
langchain-mcp-adapters

0 commit comments

Comments
 (0)