BKN SDK - Parse, validate, and transform Business Knowledge Network files
Project description
BKN Python SDK
Parse, validate, and transform BKN (Business Knowledge Network) files.
- 中文 README.zh.md
Install
# From PyPI (distribution name kweaver-bkn; Python import package is still bkn)
pip install kweaver-bkn
# Optional: HTTP API client extras
pip install "kweaver-bkn[api]"
# Editable from repo root
cd sdk/python
pip install -e .
# With kweaver API support (editable)
pip install -e ".[api]"
Requires Python 3.9+.
Usage
1. Parse a single file
from bkn import load
doc = load("examples/supplychain-hd/objects.bkn")
print(doc.frontmatter.type) # fragment
print(len(doc.objects)) # 12
for e in doc.objects:
print(e.id, e.name, len(e.data_properties), "properties")
2. Load a network (with includes)
The root file references sub-files via includes; load_network resolves them recursively. You can pass a file path or directory; for a directory, the root file is auto-discovered (network.bkn > network.md > index.bkn > index.md). If the root has no includes, same-directory BKN files are loaded implicitly.
from bkn import load_network
network = load_network("examples/supplychain-hd/supplychain.bkn")
# Or: network = load_network("examples/k8s-network") # directory → discovers index.bkn
print(network.root.frontmatter.name) # HD供应链业务知识网络_v2
print(len(network.all_objects)) # 12
print(len(network.all_relations)) # 14
print(len(network.all_actions)) # 0
3. Transform to kweaver JSON
Convert BKN models to JSON for ontology-manager API (see ref/ontology_import_openapi_v2.json):
from bkn import load_network
from bkn.transformers import KweaverTransformer
network = load_network("examples/supplychain-hd/supplychain.bkn")
transformer = KweaverTransformer(
branch="main",
base_version="",
id_prefix="supplychain_", # Object/relation ID prefix, e.g. po -> supplychain_po
)
# Get JSON dict
payload = transformer.to_json(network)
# payload["knowledge_network"] - Create knowledge network request body
# payload["object_types"] - Object types list
# payload["relation_types"] - Relation types list
# Or write to files
transformer.to_files(network, "output/")
# Creates: output/knowledge_network.json, object_types.json, relation_types.json
4. Import to kweaver via API
Import a BKN network directly to kweaver ontology-manager. Requires pip install -e ".[api]".
Two API modes: internal (default, no token) and external (Bearer token).
Internal API (inside cluster, account headers only):
from bkn import load_network
from bkn.transformers import KweaverClient, KweaverTransformer
network = load_network("examples/supplychain-hd/supplychain.bkn")
client = KweaverClient(
base_url="http://ontology-manager-svc:13014", # or KWEAVER_BASE_URL
account_id="your_account_id",
account_type="your_account_type",
business_domain="your_domain_id",
internal=True, # default
)
transformer = KweaverTransformer(id_prefix="supplychain_")
result = client.import_network(network, transformer)
External API (Bearer token):
client = KweaverClient(
base_url="https://your-gateway/api",
token="your_bearer_token", # or KWEAVER_TOKEN
account_id="your_account_id",
account_type="your_account_type",
business_domain="your_domain_id",
internal=False,
)
result = client.import_network(network, transformer)
# result.knowledge_network_id -> created knowledge network ID
# result.object_types_created -> number of object types created
# result.relation_types_created -> number of relation types created
# result.errors -> list of errors (if any)
# result.success -> True if no errors
Dry-run mode (transform only, no API calls):
result = client.import_network(network, transformer, dry_run=True)
5. Parse from string
from bkn import parse, parse_frontmatter, parse_body
text = """
---
type: object
id: my_object
name: My Object
---
## Object: my_object
**My Object** - Example object
### Data Source
| Type | ID | Name |
|------|-----|------|
| data_view | 123 | my_view |
### Data Properties
| Property | Display Name | Type | Primary Key | Display Key |
|----------|--------------|------|:-----------:|:-----------:|
| id | ID | int64 | YES | |
| name | Name | VARCHAR | | YES |
"""
doc = parse(text)
6. Access object and relation structure
obj = network.all_objects[0]
print(obj.data_source.type, obj.data_source.id)
for dp in obj.data_properties:
print(dp.property, dp.type, dp.primary_key)
for po in obj.property_overrides:
print(po.property, po.index_config) # fulltext(standard) + vector(id)
relation = network.all_relations[0]
ep = relation.endpoints[0]
print(ep.source, "->", ep.target, ep.type)
for mr in relation.mapping_rules:
print(mr.source_property, "->", mr.target_property)
6.1 Parse .bknd data files
from bkn import load
doc = load("examples/risk/data/risk_scenario.bknd")
table = doc.data_tables[0]
print(table.object_or_relation) # risk_scenario
print(table.columns) # ["scenario_id", "name", ...]
print(len(table.rows)) # number of data rows
6.2 Serialize to .bknd (to_bknd)
from bkn import to_bknd, to_bknd_from_table, load
# From structured data
md = to_bknd(object_id="risk_scenario", rows=[{"scenario_id": "s1", "name": "Test", ...}], network="recoverable-network")
# From a parsed DataTable (round-trip)
doc = load("examples/risk/data/risk_scenario.bknd")
table = doc.data_tables[0]
md = table.to_bknd()
load_network() loads only files listed in frontmatter includes; to load .bknd files, add them explicitly (e.g. includes: [data/risk_scenario.bknd]). Data tables are aggregated in network.all_data_tables.
7. Risk assessment
Objects and relations tagged with the reserved __risk__ tag in BKN participate in the built-in risk evaluation. The Action model has a runtime/computed property risk, filled by the risk assessment module based on the current scenario and risk-tagged knowledge.
evaluate_risk returns a RiskResult with three fields: decision, risk_level, and reason.
from bkn import load_network, evaluate_risk, RiskResult
network = load_network("examples/risk/index.bkn")
# Pass risk_rules when you have instance data (e.g. from a graph or API)
rules = [
{"scenario_id": "sec_t_01", "action_id": "restart_erp", "allowed": False, "risk_level": 5, "reason": "月末封网"},
]
result = evaluate_risk(network, "restart_erp", {"scenario_id": "sec_t_01"}, risk_rules=rules)
print(result.decision) # "not_allow"
print(result.risk_level) # 5
print(result.reason) # "月末封网"
Custom evaluator — inject your own logic:
def my_evaluator(network, action_id, context, risk_rules=None, **kwargs):
if action_id == "grant_root_admin":
return RiskResult(decision="not_allow", risk_level=5, reason="全局禁止提权")
return RiskResult(decision="unknown")
result = evaluate_risk(network, "grant_root_admin", {}, evaluator=my_evaluator)
print(result.decision) # "not_allow"
print(result.risk_level) # 5
- Tagging: In BKN, add
- **Tags**: __risk__to definitions that participate in the built-in risk evaluation (reserved tag; users must not use it for custom purposes). - RiskResult:
decision("allow" | "not_allow" | "unknown"),risk_level(int | None, 0–5 recommended),reason(str). - Custom evaluator: Pass
evaluator=my_functo fully replace the built-in logic; the evaluator must returnRiskResult.
Update model (no-patch)
- Add/modify: Import
.bknfiles; each definition is upserted by(network, type, id). - Delete: Use
plan_delete()/network_without()for planning and in-memory simulation; deletion is not expressed in BKN files, and persistence is handled by the consumer.
Modules
| Module | Description |
|---|---|
bkn.models |
Dataclass models: BknDocument, BknObject, Relation, Action, Risk, Connection, DataProperty, PropertyOverride, etc. |
bkn.parser |
Parsing: parse(), parse_frontmatter(), parse_body(); supports EN/CN table headers and ## Risk: blocks |
bkn.loader |
Loading: load(path), load_network(path_or_dir); root discovery (network.bkn > index.bkn); auto-resolves includes; implicit same-dir when no includes |
bkn.risk |
Risk assessment: evaluate_risk(...) -> RiskResult; RiskResult(decision, risk_level, reason) |
bkn.delete |
Delete API: DeleteTarget, plan_delete(), network_without() |
bkn.checksum |
Checksum: generate_checksum_file() validates first, then writes CHECKSUM; verify_checksum_file() checks it. SKILL.md is included in checksum computation |
bkn.tar |
pack_to_tar(source_dir, output_path, gzip=False) — Pack BKN directory to tar. On macOS sets COPYFILE_DISABLE=1 to avoid AppleDouble files |
bkn.transformers.base |
Abstract Transformer base class with to_json() and to_files() interface |
bkn.transformers.kweaver |
KweaverTransformer, KweaverClient; outputs kweaver import JSON |
KweaverTransformer parameters
| Parameter | Description | Default |
|---|---|---|
branch |
Branch name | "main" |
base_version |
Base version string | "" |
id_prefix |
Object/relation ID prefix (e.g. supplychain_ makes po -> supplychain_po) |
"" |
SKILL.md Compatibility
The SDK is fully compatible with agentskills.io SKILL directories:
load_network(dir)auto-discoversnetwork.bkn(orindex.bkn) in a Skill directory;SKILL.mddoes not interfere with network loading.generate_checksum_file()includesSKILL.mdin its checksum computation, ensuring Skill description changes are auditable alongside BKN schema changes.- The recommended layout places both
SKILL.mdandnetwork.bknin the same directory —SKILL.mdmanages Agent workflows whilenetwork.bkndeclares the BKN network topology.
Testing
cd sdk/python
pip install -e ".[dev]"
python -m pytest tests/ -v
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file kweaver_bkn-0.1.2.tar.gz.
File metadata
- Download URL: kweaver_bkn-0.1.2.tar.gz
- Upload date:
- Size: 48.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a45ecde7288b6d6a29234abbc0661493e31e0ae133b90fb6cdc649eeb164d253
|
|
| MD5 |
5586eb3c4b90b75e261bc5f140feb511
|
|
| BLAKE2b-256 |
98591c477d87fd1d7abdce48465afe6b97cc6c1c84e636317354807c82996230
|
File details
Details for the file kweaver_bkn-0.1.2-py3-none-any.whl.
File metadata
- Download URL: kweaver_bkn-0.1.2-py3-none-any.whl
- Upload date:
- Size: 37.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b498592fb8e0d645f7919ce1307c6f4a701e5d02354c1ab83c45288d3aff39df
|
|
| MD5 |
be22ff56b6161e3684bed6f99634aae6
|
|
| BLAKE2b-256 |
c4e40daae4bd3ab14cba9ef1f07bd73a7798ed711e7385286dc98d3173b00344
|