eil-card 0.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.
@@ -0,0 +1,25 @@
1
+ node_modules/
2
+ dist/
3
+ __pycache__/
4
+ *.py[cod]
5
+ .next/
6
+ .env
7
+ .env.local
8
+ .env.production
9
+ .env.prod
10
+ *.tsbuildinfo
11
+ drizzle/meta/
12
+ .DS_Store
13
+ Thumbs.db
14
+
15
+ # Internal planning — keep local, do not publish
16
+ digital.md
17
+ saha-analizi.md
18
+ is-plani.md
19
+ faz.md
20
+ pilot-sektor.md
21
+ teknik-stack.md
22
+ .cursor/*
23
+ !.cursor/rules/
24
+ !.cursor/rules/**
25
+ schema/examples/organization.sinyalle.json
@@ -0,0 +1,162 @@
1
+ Metadata-Version: 2.4
2
+ Name: eil-card
3
+ Version: 0.1.1
4
+ Summary: EIL Card Python SDK — resolve verified entity identity for AI agents
5
+ Project-URL: Homepage, https://eilcard.com
6
+ Project-URL: Documentation, https://eilcard.com/docs/agents
7
+ Project-URL: Repository, https://github.com/Mendocan/eilcard
8
+ Project-URL: Issues, https://github.com/Mendocan/eilcard/issues
9
+ Author: EIL Card
10
+ License-Expression: MIT
11
+ Keywords: agents,crewai,digital-card,eil,entity-identity,langchain
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Topic :: Software Development :: Libraries
21
+ Requires-Python: >=3.10
22
+ Requires-Dist: requests>=2.31
23
+ Provides-Extra: all
24
+ Requires-Dist: crewai>=0.80; extra == 'all'
25
+ Requires-Dist: langchain-core>=0.3; extra == 'all'
26
+ Requires-Dist: llama-index-core>=0.11; extra == 'all'
27
+ Provides-Extra: crewai
28
+ Requires-Dist: crewai>=0.80; extra == 'crewai'
29
+ Provides-Extra: crypto
30
+ Requires-Dist: cryptography>=42; extra == 'crypto'
31
+ Provides-Extra: dev
32
+ Requires-Dist: pytest>=8; extra == 'dev'
33
+ Requires-Dist: responses>=0.25; extra == 'dev'
34
+ Provides-Extra: langchain
35
+ Requires-Dist: langchain-core>=0.3; extra == 'langchain'
36
+ Provides-Extra: llamaindex
37
+ Requires-Dist: llama-index-core>=0.11; extra == 'llamaindex'
38
+ Description-Content-Type: text/markdown
39
+
40
+ # EIL Card Python SDK (`eil-card`)
41
+
42
+ Resolve verified organization and person identity from the EIL Card registry — with LangChain, CrewAI, and LlamaIndex integrations.
43
+
44
+ ## Install
45
+
46
+ ```bash
47
+ pip install eil-card
48
+ ```
49
+
50
+ Optional framework extras:
51
+
52
+ ```bash
53
+ pip install eil-card[langchain]
54
+ pip install eil-card[llamaindex]
55
+ pip install eil-card[crewai]
56
+ pip install eil-card[all]
57
+ ```
58
+
59
+ ## Quick start
60
+
61
+ ```python
62
+ from eil_card import DigitalCard, discover_capabilities, discover_act_capabilities
63
+
64
+ result = DigitalCard.resolve(domain="sinyalle.com")
65
+ card = result["card"]
66
+ print(card["name"]["official"], card.get("verified"))
67
+
68
+ caps = discover_capabilities(card)
69
+ if caps["available"]:
70
+ print("Gateway:", caps["agent_gateway"])
71
+
72
+ act = discover_act_capabilities(card)
73
+ print("Write/act scopes:", act["scopes_parsed"]["write"], act["scopes_parsed"]["act"])
74
+ ```
75
+
76
+ ## LangChain
77
+
78
+ ```python
79
+ from eil_card.integrations.langchain import create_eil_resolve_tool
80
+
81
+ tool = create_eil_resolve_tool()
82
+ # tools = [tool]
83
+ ```
84
+
85
+ Tool name matches the TypeScript SDK: `resolve_entity_identity`.
86
+
87
+ ## CrewAI
88
+
89
+ ```python
90
+ from crewai import Agent
91
+ from eil_card.integrations.crewai import create_eil_resolve_crewai_tool
92
+
93
+ resolve_tool = create_eil_resolve_crewai_tool()
94
+ agent = Agent(role="Researcher", goal="Verify entities", tools=[resolve_tool])
95
+ ```
96
+
97
+ ## LlamaIndex
98
+
99
+ ```python
100
+ from eil_card.integrations.llamaindex import EILReader
101
+
102
+ docs = EILReader().load_data(domain="sinyalle.com")
103
+ ```
104
+
105
+ ## JWS trust (Registry+)
106
+
107
+ ```python
108
+ from eil_card import DigitalCard
109
+
110
+ result = DigitalCard.resolve(domain="sinyalle.com", verify_jws=True)
111
+ print(result.get("trust", {}).get("jws"))
112
+
113
+ # Crypto verify: pip install eil-card[crypto]
114
+ result = DigitalCard.resolve(
115
+ domain="sinyalle.com",
116
+ verify_jws={"public_key_pem": open("registry-public.pem").read(), "require_valid": True},
117
+ )
118
+ ```
119
+
120
+ ## Agent act headers (pilot gateway)
121
+
122
+ ```python
123
+ from eil_card import build_idempotency_key, build_agent_act_headers, agent_act_headers_to_fetch
124
+
125
+ key = build_idempotency_key(
126
+ agent_client_id="my-agent",
127
+ action_id="create_post",
128
+ entity_id="sinyalle.com",
129
+ nonce="run-1",
130
+ )
131
+ headers = agent_act_headers_to_fetch(
132
+ build_agent_act_headers(
133
+ access_token="...",
134
+ idempotency_key=key,
135
+ action_id="create_post",
136
+ card_id="sinyalle.com",
137
+ )
138
+ )
139
+ ```
140
+
141
+ ## Development
142
+
143
+ ```bash
144
+ cd packages/python
145
+ pip install -e ".[dev]"
146
+ pytest
147
+ ```
148
+
149
+ ## Publish (maintainers)
150
+
151
+ ```bash
152
+ pip install build twine
153
+ python -m build
154
+ twine upload dist/*
155
+ ```
156
+
157
+ Set `PYPI_API_TOKEN` in the environment or `~/.pypirc`.
158
+
159
+ ## Docs
160
+
161
+ - https://eilcard.com/docs/agents
162
+ - TypeScript SDK parity: `packages/sdk/SDK.md`
@@ -0,0 +1,123 @@
1
+ # EIL Card Python SDK (`eil-card`)
2
+
3
+ Resolve verified organization and person identity from the EIL Card registry — with LangChain, CrewAI, and LlamaIndex integrations.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ pip install eil-card
9
+ ```
10
+
11
+ Optional framework extras:
12
+
13
+ ```bash
14
+ pip install eil-card[langchain]
15
+ pip install eil-card[llamaindex]
16
+ pip install eil-card[crewai]
17
+ pip install eil-card[all]
18
+ ```
19
+
20
+ ## Quick start
21
+
22
+ ```python
23
+ from eil_card import DigitalCard, discover_capabilities, discover_act_capabilities
24
+
25
+ result = DigitalCard.resolve(domain="sinyalle.com")
26
+ card = result["card"]
27
+ print(card["name"]["official"], card.get("verified"))
28
+
29
+ caps = discover_capabilities(card)
30
+ if caps["available"]:
31
+ print("Gateway:", caps["agent_gateway"])
32
+
33
+ act = discover_act_capabilities(card)
34
+ print("Write/act scopes:", act["scopes_parsed"]["write"], act["scopes_parsed"]["act"])
35
+ ```
36
+
37
+ ## LangChain
38
+
39
+ ```python
40
+ from eil_card.integrations.langchain import create_eil_resolve_tool
41
+
42
+ tool = create_eil_resolve_tool()
43
+ # tools = [tool]
44
+ ```
45
+
46
+ Tool name matches the TypeScript SDK: `resolve_entity_identity`.
47
+
48
+ ## CrewAI
49
+
50
+ ```python
51
+ from crewai import Agent
52
+ from eil_card.integrations.crewai import create_eil_resolve_crewai_tool
53
+
54
+ resolve_tool = create_eil_resolve_crewai_tool()
55
+ agent = Agent(role="Researcher", goal="Verify entities", tools=[resolve_tool])
56
+ ```
57
+
58
+ ## LlamaIndex
59
+
60
+ ```python
61
+ from eil_card.integrations.llamaindex import EILReader
62
+
63
+ docs = EILReader().load_data(domain="sinyalle.com")
64
+ ```
65
+
66
+ ## JWS trust (Registry+)
67
+
68
+ ```python
69
+ from eil_card import DigitalCard
70
+
71
+ result = DigitalCard.resolve(domain="sinyalle.com", verify_jws=True)
72
+ print(result.get("trust", {}).get("jws"))
73
+
74
+ # Crypto verify: pip install eil-card[crypto]
75
+ result = DigitalCard.resolve(
76
+ domain="sinyalle.com",
77
+ verify_jws={"public_key_pem": open("registry-public.pem").read(), "require_valid": True},
78
+ )
79
+ ```
80
+
81
+ ## Agent act headers (pilot gateway)
82
+
83
+ ```python
84
+ from eil_card import build_idempotency_key, build_agent_act_headers, agent_act_headers_to_fetch
85
+
86
+ key = build_idempotency_key(
87
+ agent_client_id="my-agent",
88
+ action_id="create_post",
89
+ entity_id="sinyalle.com",
90
+ nonce="run-1",
91
+ )
92
+ headers = agent_act_headers_to_fetch(
93
+ build_agent_act_headers(
94
+ access_token="...",
95
+ idempotency_key=key,
96
+ action_id="create_post",
97
+ card_id="sinyalle.com",
98
+ )
99
+ )
100
+ ```
101
+
102
+ ## Development
103
+
104
+ ```bash
105
+ cd packages/python
106
+ pip install -e ".[dev]"
107
+ pytest
108
+ ```
109
+
110
+ ## Publish (maintainers)
111
+
112
+ ```bash
113
+ pip install build twine
114
+ python -m build
115
+ twine upload dist/*
116
+ ```
117
+
118
+ Set `PYPI_API_TOKEN` in the environment or `~/.pypirc`.
119
+
120
+ ## Docs
121
+
122
+ - https://eilcard.com/docs/agents
123
+ - TypeScript SDK parity: `packages/sdk/SDK.md`
@@ -0,0 +1,64 @@
1
+ """EIL Card Python SDK — resolve verified entity identity for AI agents."""
2
+
3
+ from eil_card.act import (
4
+ agent_act_headers_to_fetch,
5
+ build_agent_act_headers,
6
+ build_idempotency_key,
7
+ discover_act_capabilities,
8
+ parse_capability_scopes,
9
+ )
10
+ from eil_card.agent_tool import (
11
+ format_resolve_tool_error,
12
+ format_resolve_tool_result,
13
+ invoke_eil_resolve,
14
+ invoke_eil_resolve_async,
15
+ )
16
+ from eil_card.capabilities import discover_capabilities
17
+ from eil_card.client import DigitalCard, DigitalCardClient, normalize_domain
18
+ from eil_card.errors import (
19
+ CardNotFoundError,
20
+ DigitalCardError,
21
+ InvalidResolveInputError,
22
+ JwsVerificationError,
23
+ RegistryError,
24
+ SchemaValidationError,
25
+ )
26
+ from eil_card.jws import canonical_card_without_signatures, verify_registry_jws
27
+ from eil_card.tool_schema import (
28
+ EIL_RESOLVE_TOOL_DESCRIPTION,
29
+ EIL_RESOLVE_TOOL_NAME,
30
+ build_eil_resolve_tool_definitions,
31
+ build_resolve_input_json_schema,
32
+ )
33
+ from eil_card.types import SCHEMA_VERSION
34
+
35
+ __all__ = [
36
+ "SCHEMA_VERSION",
37
+ "DigitalCard",
38
+ "DigitalCardClient",
39
+ "normalize_domain",
40
+ "discover_capabilities",
41
+ "discover_act_capabilities",
42
+ "parse_capability_scopes",
43
+ "build_idempotency_key",
44
+ "build_agent_act_headers",
45
+ "agent_act_headers_to_fetch",
46
+ "invoke_eil_resolve",
47
+ "invoke_eil_resolve_async",
48
+ "format_resolve_tool_result",
49
+ "format_resolve_tool_error",
50
+ "EIL_RESOLVE_TOOL_NAME",
51
+ "EIL_RESOLVE_TOOL_DESCRIPTION",
52
+ "build_resolve_input_json_schema",
53
+ "build_eil_resolve_tool_definitions",
54
+ "DigitalCardError",
55
+ "CardNotFoundError",
56
+ "InvalidResolveInputError",
57
+ "JwsVerificationError",
58
+ "RegistryError",
59
+ "SchemaValidationError",
60
+ "canonical_card_without_signatures",
61
+ "verify_registry_jws",
62
+ ]
63
+
64
+ __version__ = "0.1.1"
@@ -0,0 +1,98 @@
1
+ from __future__ import annotations
2
+
3
+ import re
4
+ from typing import Any
5
+
6
+ from eil_card.capabilities import discover_capabilities
7
+ from eil_card.types import DiscoveredActCapabilities, ParsedCapabilityScopes
8
+
9
+ _SCOPE_KIND_PATTERN = re.compile(r"^(read|write|act):")
10
+
11
+
12
+ def parse_capability_scopes(scopes: list[str] | None = None) -> ParsedCapabilityScopes:
13
+ result: ParsedCapabilityScopes = {
14
+ "read": [],
15
+ "write": [],
16
+ "act": [],
17
+ "unknown": [],
18
+ "all": list(scopes) if scopes else [],
19
+ }
20
+ if not scopes:
21
+ return result
22
+
23
+ for scope in scopes:
24
+ if scope.startswith("read:"):
25
+ result["read"].append(scope)
26
+ elif scope.startswith("write:"):
27
+ result["write"].append(scope)
28
+ elif scope.startswith("act:"):
29
+ result["act"].append(scope)
30
+ elif _SCOPE_KIND_PATTERN.match(scope):
31
+ result["unknown"].append(scope)
32
+ else:
33
+ result["unknown"].append(scope)
34
+
35
+ return result
36
+
37
+
38
+ def discover_act_capabilities(card: dict[str, Any]) -> DiscoveredActCapabilities:
39
+ base = discover_capabilities(card)
40
+ scopes_parsed = parse_capability_scopes(base.get("scopes"))
41
+ actions = (card.get("capabilities") or {}).get("actions")
42
+
43
+ return {
44
+ **base,
45
+ "scopes_parsed": scopes_parsed,
46
+ "actions": actions,
47
+ "has_write_or_act": bool(
48
+ scopes_parsed["write"] or scopes_parsed["act"] or (actions or [])
49
+ ),
50
+ }
51
+
52
+
53
+ def build_idempotency_key(
54
+ *,
55
+ agent_client_id: str,
56
+ action_id: str,
57
+ entity_id: str,
58
+ nonce: str,
59
+ ) -> str:
60
+ def slug(value: str) -> str:
61
+ out = value.strip().lower()
62
+ out = re.sub(r"[^a-z0-9._-]+", "-", out)
63
+ out = re.sub(r"-+", "-", out)
64
+ return out.strip("-")
65
+
66
+ return "/".join(
67
+ [
68
+ "eil-act",
69
+ slug(agent_client_id),
70
+ slug(action_id),
71
+ slug(entity_id),
72
+ slug(nonce),
73
+ ]
74
+ )
75
+
76
+
77
+ def build_agent_act_headers(
78
+ *,
79
+ access_token: str,
80
+ idempotency_key: str,
81
+ action_id: str,
82
+ card_id: str,
83
+ ) -> dict[str, str]:
84
+ return {
85
+ "authorization": f"Bearer {access_token}",
86
+ "idempotency_key": idempotency_key,
87
+ "action_id": action_id,
88
+ "card_id": card_id,
89
+ }
90
+
91
+
92
+ def agent_act_headers_to_fetch(headers: dict[str, str]) -> dict[str, str]:
93
+ return {
94
+ "Authorization": headers["authorization"],
95
+ "Idempotency-Key": headers["idempotency_key"],
96
+ "X-EIL-Action-Id": headers["action_id"],
97
+ "X-EIL-Card-Id": headers["card_id"],
98
+ }
@@ -0,0 +1,60 @@
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ from typing import Any
5
+
6
+ from eil_card.client import DigitalCard, DigitalCardClient
7
+ from eil_card.errors import InvalidResolveInputError
8
+ from eil_card.tool_schema import EIL_RESOLVE_TOOL_DESCRIPTION, EIL_RESOLVE_TOOL_NAME
9
+
10
+
11
+ async def invoke_eil_resolve_async(
12
+ *,
13
+ domain: str | None = None,
14
+ handle: str | None = None,
15
+ registry_base_url: str = "https://eilcard.com",
16
+ api_key: str | None = None,
17
+ timeout: float = 10.0,
18
+ skip_well_known_fallback: bool = False,
19
+ ) -> dict[str, Any]:
20
+ """Async wrapper — runs sync resolve in thread pool if needed by frameworks."""
21
+ return invoke_eil_resolve(
22
+ domain=domain,
23
+ handle=handle,
24
+ registry_base_url=registry_base_url,
25
+ api_key=api_key,
26
+ timeout=timeout,
27
+ skip_well_known_fallback=skip_well_known_fallback,
28
+ )
29
+
30
+
31
+ def invoke_eil_resolve(
32
+ *,
33
+ domain: str | None = None,
34
+ handle: str | None = None,
35
+ registry_base_url: str = "https://eilcard.com",
36
+ api_key: str | None = None,
37
+ timeout: float = 10.0,
38
+ skip_well_known_fallback: bool = False,
39
+ ) -> dict[str, Any]:
40
+ """Framework-agnostic handler for tool-calling agents."""
41
+ client = DigitalCardClient(
42
+ registry_base_url=registry_base_url,
43
+ api_key=api_key,
44
+ timeout=timeout,
45
+ skip_well_known_fallback=skip_well_known_fallback,
46
+ )
47
+ if domain:
48
+ return client.resolve(domain=domain)
49
+ if handle:
50
+ return client.resolve(handle=handle)
51
+ raise InvalidResolveInputError()
52
+
53
+
54
+ def format_resolve_tool_result(result: dict[str, Any]) -> str:
55
+ return json.dumps(result, indent=2, ensure_ascii=False)
56
+
57
+
58
+ def format_resolve_tool_error(entity: str, error: Exception | str) -> str:
59
+ message = str(error)
60
+ return f"Could not resolve EIL identity for {entity}: {message}"
@@ -0,0 +1,42 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any
4
+
5
+ from eil_card.types import DiscoveredCapabilities
6
+
7
+
8
+ def discover_capabilities(card: dict[str, Any]) -> DiscoveredCapabilities:
9
+ """Read capability manifest from a resolved card (Registry+ only)."""
10
+ edition = card.get("edition") or "core"
11
+
12
+ if edition != "registry_plus":
13
+ return {
14
+ "available": False,
15
+ "edition": edition,
16
+ "reason": "Capabilities require Registry+ edition (schema 1.2)",
17
+ }
18
+
19
+ caps = card.get("capabilities")
20
+ if not caps:
21
+ return {
22
+ "available": False,
23
+ "edition": edition,
24
+ "reason": "No capabilities object on card",
25
+ }
26
+
27
+ if not caps.get("agent_gateway"):
28
+ return {
29
+ "available": False,
30
+ "edition": edition,
31
+ "auth": caps.get("auth"),
32
+ "scopes": caps.get("scopes"),
33
+ "reason": "capabilities.agent_gateway is not set",
34
+ }
35
+
36
+ return {
37
+ "available": True,
38
+ "edition": edition,
39
+ "agent_gateway": caps["agent_gateway"],
40
+ "auth": caps.get("auth"),
41
+ "scopes": caps.get("scopes"),
42
+ }