|
| 1 | +# OKH-LOSH v2.4 TOML Conversion |
| 2 | + |
| 3 | +OKH-LOSH v2.4 is the TOML-based OKH manifest format defined by |
| 4 | +[iop-alliance/OpenKnowHow](https://github.com/iop-alliance/OpenKnowHow). It |
| 5 | +uses kebab-case field names and a few shapes (a repeatable `[[image]]` table, |
| 6 | +a top-level `[outer-dimensions]` table, a top-level `mass`) that have no |
| 7 | +direct equivalent in OHM's canonical model. |
| 8 | + |
| 9 | +Conversion is **one-way** (TOML → OKH). Nothing in OHM needs to export a |
| 10 | +manifest back to OKH-LOSH TOML. |
| 11 | + |
| 12 | +## Field Mapping |
| 13 | + |
| 14 | +| OKH-LOSH v2.4 field | OKH field | Notes | |
| 15 | +|---|---|---| |
| 16 | +| `okhv` | `okhv` | Passed through literally; not validated by OHM | |
| 17 | +| `name` | `title` | Rename | |
| 18 | +| `repo`, `license`, `function`, `version`, `licensor`, `organization`, `attestation`, `bom`, `readme` | Same names | Passed straight through; `license` bare strings and `licensor`/`organization` `"Name <email>"` strings/lists are already handled by `OKHManifest.from_dict()` | |
| 19 | +| `documentation-language` | `documentation_language` | Rename | |
| 20 | +| `technology-readiness-level` | `technology_readiness_level` | Rename | |
| 21 | +| `documentation-readiness-level` | `documentation_readiness_level` | Rename | |
| 22 | +| `cpc-patent-class` | `cpc_patent_class` | Rename | |
| 23 | +| `contribution-guide` | `contribution_guide` | Rename | |
| 24 | +| `tsdc` | `tsdc` | Wrapped in a list if given as a bare string | |
| 25 | +| `standard-compliance` | `standards_used` | Wrapped in a list if given as a bare string | |
| 26 | +| `manufacturing-instructions` | `making_instructions` | Each entry becomes a `DocumentRef` (`path` = the URL/file, `type=making-instructions`) | |
| 27 | +| `user-manual` | `operating_instructions` | Same pattern, `type=operating-instructions` | |
| 28 | +| `publication` | `publications` | Same pattern, `type=publications` | |
| 29 | +| `source` | `design_files` | Same pattern, `type=design-files` | |
| 30 | +| `[[software]]` | `software` | Structurally identical; `installation-guide` (kebab in the source) is renamed to `installation_guide` | |
| 31 | +| `[outer-dimensions]` | `manufacturing_specs.outer_dimensions` | Untyped dict on both sides; `width`/`depth`/`height` keys preserved as-is | |
| 32 | +| `[[image]]` | `image` + `metadata.images` | See below | |
| 33 | +| `mass` | `metadata.mass` | No top-level equivalent in OHM (only nested under a part's `mass`) | |
| 34 | +| `release` | `metadata.release` | Different concept from OHM's `Software.release` | |
| 35 | + |
| 36 | +### Image handling |
| 37 | + |
| 38 | +OKH-LOSH's `[[image]]` is a repeatable table (`location`, `depicts`, `slots`, |
| 39 | +`tags`); OHM's canonical model has a single scalar `image: Optional[str]`. |
| 40 | +The converter: |
| 41 | + |
| 42 | +1. Picks one **primary** image for the `image` field — preferring the entry |
| 43 | + tagged with the `photo-thing-main` slot, falling back to the first image |
| 44 | + with a `location`. |
| 45 | +2. Preserves the **full array** (all entries, with their `slots`/`tags`/ |
| 46 | + `depicts`) under `metadata.images`, so nothing is lost even though only |
| 47 | + one image is a first-class field. |
| 48 | + |
| 49 | +## Access Methods |
| 50 | + |
| 51 | +- **CLI**: `ohm convert from-okh-losh` |
| 52 | +- **API**: `POST /v1/api/convert/from-okh-losh` |
| 53 | +- **Python**: `OkhLoshConverter` class in `src.core.services.okh_losh_converter` |
| 54 | + |
| 55 | +## Quick Start |
| 56 | + |
| 57 | +### CLI |
| 58 | + |
| 59 | +```bash |
| 60 | +# Convert an OKH-LOSH TOML manifest → OKH manifest (JSON) |
| 61 | +ohm convert from-okh-losh my-project.okh.toml -o my-project.okh.json |
| 62 | + |
| 63 | +# Output as YAML |
| 64 | +ohm convert from-okh-losh my-project.okh.toml --format yaml |
| 65 | +``` |
| 66 | + |
| 67 | +### API |
| 68 | + |
| 69 | +```bash |
| 70 | +# OKH-LOSH TOML → OKH (upload .toml, get JSON back) |
| 71 | +curl -X POST http://localhost:8001/v1/api/convert/from-okh-losh \ |
| 72 | + -F "toml_file=@my-project.okh.toml" |
| 73 | +``` |
| 74 | + |
| 75 | +### Python |
| 76 | + |
| 77 | +```python |
| 78 | +from src.core.services.okh_losh_converter import OkhLoshConverter |
| 79 | + |
| 80 | +converter = OkhLoshConverter() |
| 81 | +manifest = converter.okh_losh_to_okh("my-project.okh.toml") |
| 82 | +print(manifest.title) |
| 83 | +``` |
| 84 | + |
| 85 | +## CLI Reference |
| 86 | + |
| 87 | +### `ohm convert from-okh-losh` |
| 88 | + |
| 89 | +``` |
| 90 | +Usage: ohm convert from-okh-losh [OPTIONS] TOML_FILE |
| 91 | +
|
| 92 | + Convert an OKH-LOSH v2.4 TOML manifest to an OKH manifest. |
| 93 | +
|
| 94 | +Options: |
| 95 | + -o, --output PATH Output file path |
| 96 | + --format [json|yaml] Output format (default: json) |
| 97 | + -v, --verbose Enable verbose output |
| 98 | + --json Output in JSON format |
| 99 | +``` |
| 100 | + |
| 101 | +## API Reference |
| 102 | + |
| 103 | +### `POST /v1/api/convert/from-okh-losh` |
| 104 | + |
| 105 | +Accepts an OKH-LOSH `.toml` file upload and returns the parsed OKH manifest |
| 106 | +as JSON. |
| 107 | + |
| 108 | +**Request**: Multipart form upload with a `toml_file` field. |
| 109 | + |
| 110 | +**Response**: `ConvertFromOkhLoshResponse` containing the full manifest and |
| 111 | +conversion metadata. |
| 112 | + |
| 113 | +## Bulk Import |
| 114 | + |
| 115 | +For importing a directory of many OKH-LOSH TOML files at once (rather than |
| 116 | +one file via the CLI/API), see `scripts/import_okh_losh_batch.py` |
| 117 | +(`scripts/registry.toml` entry `import_okh_losh_batch`), which converts each |
| 118 | +file, validates and auto-fixes it, and persists it through |
| 119 | +`OKHService.create()`. |
0 commit comments