echa-cli 1.0.1__tar.gz → 1.1.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {echa_cli-1.0.1 → echa_cli-1.1.1}/PKG-INFO +9 -3
- {echa_cli-1.0.1 → echa_cli-1.1.1}/README.md +8 -2
- {echa_cli-1.0.1 → echa_cli-1.1.1}/echa_cli.egg-info/PKG-INFO +9 -3
- {echa_cli-1.0.1 → echa_cli-1.1.1}/echa_mcp/cli.py +44 -1
- {echa_cli-1.0.1 → echa_cli-1.1.1}/echa_mcp/clients/echa_client.py +1 -0
- {echa_cli-1.0.1 → echa_cli-1.1.1}/pyproject.toml +1 -1
- {echa_cli-1.0.1 → echa_cli-1.1.1}/LICENSE +0 -0
- {echa_cli-1.0.1 → echa_cli-1.1.1}/echa_cli.egg-info/SOURCES.txt +0 -0
- {echa_cli-1.0.1 → echa_cli-1.1.1}/echa_cli.egg-info/dependency_links.txt +0 -0
- {echa_cli-1.0.1 → echa_cli-1.1.1}/echa_cli.egg-info/entry_points.txt +0 -0
- {echa_cli-1.0.1 → echa_cli-1.1.1}/echa_cli.egg-info/requires.txt +0 -0
- {echa_cli-1.0.1 → echa_cli-1.1.1}/echa_cli.egg-info/top_level.txt +0 -0
- {echa_cli-1.0.1 → echa_cli-1.1.1}/echa_mcp/__init__.py +0 -0
- {echa_cli-1.0.1 → echa_cli-1.1.1}/echa_mcp/clients/__init__.py +0 -0
- {echa_cli-1.0.1 → echa_cli-1.1.1}/echa_mcp/data/__init__.py +0 -0
- {echa_cli-1.0.1 → echa_cli-1.1.1}/echa_mcp/data/hcode_mapping.py +0 -0
- {echa_cli-1.0.1 → echa_cli-1.1.1}/echa_mcp/models/__init__.py +0 -0
- {echa_cli-1.0.1 → echa_cli-1.1.1}/echa_mcp/models/classification.py +0 -0
- {echa_cli-1.0.1 → echa_cli-1.1.1}/echa_mcp/models/substance.py +0 -0
- {echa_cli-1.0.1 → echa_cli-1.1.1}/echa_mcp/models/toxicology.py +0 -0
- {echa_cli-1.0.1 → echa_cli-1.1.1}/echa_mcp/parsers/__init__.py +0 -0
- {echa_cli-1.0.1 → echa_cli-1.1.1}/echa_mcp/parsers/common.py +0 -0
- {echa_cli-1.0.1 → echa_cli-1.1.1}/echa_mcp/parsers/section2_parser.py +0 -0
- {echa_cli-1.0.1 → echa_cli-1.1.1}/echa_mcp/parsers/section7_parser.py +0 -0
- {echa_cli-1.0.1 → echa_cli-1.1.1}/echa_mcp/server.py +0 -0
- {echa_cli-1.0.1 → echa_cli-1.1.1}/echa_mcp/tools/__init__.py +0 -0
- {echa_cli-1.0.1 → echa_cli-1.1.1}/echa_mcp/tools/clp_classification.py +0 -0
- {echa_cli-1.0.1 → echa_cli-1.1.1}/echa_mcp/tools/harmonised_classification.py +0 -0
- {echa_cli-1.0.1 → echa_cli-1.1.1}/echa_mcp/tools/reach_classification.py +0 -0
- {echa_cli-1.0.1 → echa_cli-1.1.1}/echa_mcp/tools/substance.py +0 -0
- {echa_cli-1.0.1 → echa_cli-1.1.1}/echa_mcp/tools/toxicology.py +0 -0
- {echa_cli-1.0.1 → echa_cli-1.1.1}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: echa-cli
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.1.1
|
|
4
4
|
Summary: ECHA Chemical Data CLI — query European Chemicals Agency data from the command line or MCP server
|
|
5
5
|
Author: MagaritaZhu
|
|
6
6
|
License-Expression: MIT
|
|
@@ -60,13 +60,19 @@ Dynamic: license-file
|
|
|
60
60
|
### 安装
|
|
61
61
|
|
|
62
62
|
```bash
|
|
63
|
-
|
|
63
|
+
# pip
|
|
64
|
+
pip install echa-cli
|
|
65
|
+
|
|
66
|
+
# 或 uv(推荐,自动隔离环境)
|
|
67
|
+
uv tool install echa-cli
|
|
68
|
+
|
|
69
|
+
# 或从源码
|
|
64
70
|
pip install -e .
|
|
65
71
|
```
|
|
66
72
|
|
|
67
73
|
安装后提供两个命令:
|
|
68
|
-
- `echa-mcp` — 启动 MCP Server(供 AI 助手使用)
|
|
69
74
|
- `echa-cli` — 命令行工具(供终端直接使用)
|
|
75
|
+
- `echa-mcp` — 启动 MCP Server(供 AI 助手使用)
|
|
70
76
|
|
|
71
77
|
### 方式一:CLI 命令行
|
|
72
78
|
|
|
@@ -28,13 +28,19 @@
|
|
|
28
28
|
### 安装
|
|
29
29
|
|
|
30
30
|
```bash
|
|
31
|
-
|
|
31
|
+
# pip
|
|
32
|
+
pip install echa-cli
|
|
33
|
+
|
|
34
|
+
# 或 uv(推荐,自动隔离环境)
|
|
35
|
+
uv tool install echa-cli
|
|
36
|
+
|
|
37
|
+
# 或从源码
|
|
32
38
|
pip install -e .
|
|
33
39
|
```
|
|
34
40
|
|
|
35
41
|
安装后提供两个命令:
|
|
36
|
-
- `echa-mcp` — 启动 MCP Server(供 AI 助手使用)
|
|
37
42
|
- `echa-cli` — 命令行工具(供终端直接使用)
|
|
43
|
+
- `echa-mcp` — 启动 MCP Server(供 AI 助手使用)
|
|
38
44
|
|
|
39
45
|
### 方式一:CLI 命令行
|
|
40
46
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: echa-cli
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.1.1
|
|
4
4
|
Summary: ECHA Chemical Data CLI — query European Chemicals Agency data from the command line or MCP server
|
|
5
5
|
Author: MagaritaZhu
|
|
6
6
|
License-Expression: MIT
|
|
@@ -60,13 +60,19 @@ Dynamic: license-file
|
|
|
60
60
|
### 安装
|
|
61
61
|
|
|
62
62
|
```bash
|
|
63
|
-
|
|
63
|
+
# pip
|
|
64
|
+
pip install echa-cli
|
|
65
|
+
|
|
66
|
+
# 或 uv(推荐,自动隔离环境)
|
|
67
|
+
uv tool install echa-cli
|
|
68
|
+
|
|
69
|
+
# 或从源码
|
|
64
70
|
pip install -e .
|
|
65
71
|
```
|
|
66
72
|
|
|
67
73
|
安装后提供两个命令:
|
|
68
|
-
- `echa-mcp` — 启动 MCP Server(供 AI 助手使用)
|
|
69
74
|
- `echa-cli` — 命令行工具(供终端直接使用)
|
|
75
|
+
- `echa-mcp` — 启动 MCP Server(供 AI 助手使用)
|
|
70
76
|
|
|
71
77
|
### 方式一:CLI 命令行
|
|
72
78
|
|
|
@@ -3,13 +3,15 @@
|
|
|
3
3
|
ECHA Chemical Data CLI — query European Chemicals Agency data from the command line.
|
|
4
4
|
|
|
5
5
|
Usage:
|
|
6
|
+
echa-cli search ethanol
|
|
7
|
+
echa-cli search 50-00-0
|
|
6
8
|
echa-cli substance-info 100.000.002
|
|
7
9
|
echa-cli harmonised 100.000.002
|
|
8
10
|
echa-cli tox-summary 100.000.002
|
|
9
|
-
echa-cli tox-studies 100.000.002 --section 7.2 --max-studies 10
|
|
10
11
|
"""
|
|
11
12
|
|
|
12
13
|
import asyncio
|
|
14
|
+
import json
|
|
13
15
|
import sys
|
|
14
16
|
from typing import Optional
|
|
15
17
|
|
|
@@ -41,6 +43,47 @@ def _run_async(coro):
|
|
|
41
43
|
loop.close()
|
|
42
44
|
|
|
43
45
|
|
|
46
|
+
# ─── Search (resolve CAS/name → substance_index) ─────────────
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
@app.command()
|
|
50
|
+
def search(
|
|
51
|
+
query: str = typer.Argument(help="CAS number, chemical name, or EC number"),
|
|
52
|
+
max_results: int = typer.Option(5, help="Maximum results to return"),
|
|
53
|
+
):
|
|
54
|
+
"""Search ECHA for a substance by CAS number, name, or EC number. Returns substance_index."""
|
|
55
|
+
async def _search():
|
|
56
|
+
from .clients.echa_client import get_client
|
|
57
|
+
|
|
58
|
+
client = get_client()
|
|
59
|
+
http_client = await client._get_client()
|
|
60
|
+
|
|
61
|
+
url = "/api-substance/v1/substance"
|
|
62
|
+
params = {"searchText": query, "pageIndex": 1, "pageSize": max_results}
|
|
63
|
+
resp = await http_client.get(url, params=params)
|
|
64
|
+
resp.raise_for_status()
|
|
65
|
+
data = resp.json()
|
|
66
|
+
|
|
67
|
+
items = data.get("items", [])
|
|
68
|
+
if not items:
|
|
69
|
+
return json.dumps({"error": f"No results for '{query}'"}, indent=2)
|
|
70
|
+
|
|
71
|
+
results = []
|
|
72
|
+
for item in items[:max_results]:
|
|
73
|
+
idx = item.get("substanceIndex", {})
|
|
74
|
+
results.append({
|
|
75
|
+
"substance_index": idx.get("rmlId", ""),
|
|
76
|
+
"name": idx.get("rmlName", ""),
|
|
77
|
+
"cas_number": idx.get("rmlCas", ""),
|
|
78
|
+
"ec_number": idx.get("rmlEc", ""),
|
|
79
|
+
"molecular_formula": idx.get("rmlMolFormula", ""),
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
return json.dumps({"query": query, "total": len(results), "results": results}, ensure_ascii=False, indent=2)
|
|
83
|
+
|
|
84
|
+
_run_async(_search())
|
|
85
|
+
|
|
86
|
+
|
|
44
87
|
# ─── Substance Info ───────────────────────────────────────────
|
|
45
88
|
|
|
46
89
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|