Skip to content

Commit 84712a0

Browse files
committed
Generate API
1 parent 98ff70b commit 84712a0

File tree

11 files changed

+429
-0
lines changed

11 files changed

+429
-0
lines changed

docs/generate.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import shutil
2+
import os
3+
4+
shutil.copy("../README.md", "sphinx/source/api/Introduction.md")
5+
6+
for file_ in os.listdir("../examples"):
7+
if ("document" in file_) or ("README" in file_):
8+
shutil.copy(
9+
"../examples/%s" % file_, os.path.join("sphinx/source/api/examples", file_)
10+
)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Modelspec
2+
3+
4+
[![Continuous builds](https://github.com/ModECI/modelspec/actions/workflows/ci.yml/badge.svg)](https://github.com/ModECI/modelspec/actions/workflows/ci.yml) [![PyPI](https://img.shields.io/pypi/v/modelspec)](https://pypi.org/project/modelspec/)
5+
6+
7+
Functionality for specifying the structure of models & enabling automatic serialization to them (e.g. in JSON and YAML format).
8+
9+
This package is being used by [NeuroMLlite](https://github.com/NeuroML/NeuroMLlite) & [MDF](https://github.com/ModECI/MDF).
10+
11+
For an example of the use of this package see [here](examples/README.md).
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Some simple examples of the use of Modelspec
2+
3+
See also packages [NeuroMLlite](https://github.com/NeuroML/NeuroMLlite) & [MDF](https://github.com/ModECI/MDF) for usage of Modelspec.
4+
5+
## A simple definition of the structure of a Document in modelspec
6+
7+
### 1) Define the structure of a "Document"
8+
9+
A Python file defining the structure of the Document, as well as saving an instance (see below) can be found here: [document.py](document.py).
10+
11+
12+
### 2) Generate human and machine readable specifications of what can be in a Document
13+
14+
A generated Markdown file where the structure of a Document is defined is here: [document.md](document.md). To generate this:
15+
```
16+
doc_md = doc.generate_documentation(format="markdown")
17+
```
18+
19+
A similar file can be done in reStructuredText (RST) format ([document.rst](document.rst))
20+
```
21+
doc_rst = doc.generate_documentation(format="rst")
22+
```
23+
24+
For a machine readable version of this, generate in dict format and save to [YAML](document.specification.yaml) or [JSON](document.specification.json).
25+
```
26+
doc_dict = doc.generate_documentation(format="dict")
27+
28+
with open("document.specification.json", "w") as d:
29+
d.write(json.dumps(doc_dict, indent=4))
30+
31+
with open("document.specification.yaml", "w") as d:
32+
d.write(yaml.dump(doc_dict, indent=4, sort_keys=False))
33+
```
34+
35+
### 3) Create an instance of a Document
36+
37+
The actual instance of a document which is built (in [document.py](document.py)) can be saved in [YAML](document.yaml) or [JSON](document.json) format or [BSON](document.bson) format:
38+
```
39+
doc = Document(id="MyBook")
40+
doc.title = "My life in Python"
41+
42+
a = Section(id="Abstract")
43+
doc.sections.append(a)
44+
45+
...
46+
47+
doc.to_json_file("document.json")
48+
doc.to_yaml_file("document.yaml")
49+
doc.to_bson_file("document.bson")
50+
```
222 Bytes
Binary file not shown.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"MyBook": {
3+
"title": "My life in Python",
4+
"sections": {
5+
"Abstract": {
6+
"paragraphs": [
7+
{
8+
"contents": "Blah blah blah"
9+
},
10+
{
11+
"contents": "Blah2"
12+
}
13+
]
14+
},
15+
"Chapter 1": {
16+
"paragraphs": [
17+
{
18+
"contents": "More..."
19+
}
20+
]
21+
}
22+
}
23+
}
24+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
## Document
2+
A model for documents.
3+
4+
### Allowed parameters
5+
<table>
6+
<tr>
7+
<td><b>id</b></td>
8+
<td>str</td>
9+
<td><i>The unique id of the document</i></td>
10+
</tr>
11+
12+
13+
<tr>
14+
<td><b>title</b></td>
15+
<td>str</td>
16+
<td><i>The document title</i></td>
17+
</tr>
18+
19+
20+
<tr>
21+
<td><b>ISBN</b></td>
22+
<td>int</td>
23+
<td><i>International Standard Book Number</i></td>
24+
</tr>
25+
26+
27+
</table>
28+
29+
### Allowed children
30+
<table>
31+
<tr>
32+
<td><b>sections</b></td>
33+
<td><a href="#section">Section</a></td>
34+
<td><i>The sections of the document</i></td>
35+
</tr>
36+
37+
38+
</table>
39+
40+
## Section
41+
A model of a section of the <a href="#document">Document</a>. Will contain one <a href="#paragraph">Paragraph</a> or more, i.e the <a href="#paragraph">Paragraph</a>(s) in the section, probably related to the <b>title</b> of the `Document <#document>`_.
42+
43+
### Allowed parameters
44+
<table>
45+
<tr>
46+
<td><b>id</b></td>
47+
<td>str</td>
48+
<td><i>The id of the section</i></td>
49+
</tr>
50+
51+
52+
</table>
53+
54+
### Allowed children
55+
<table>
56+
<tr>
57+
<td><b>paragraphs</b></td>
58+
<td><a href="#paragraph">Paragraph</a></td>
59+
<td><i>The paragraphs</i></td>
60+
</tr>
61+
62+
63+
</table>
64+
65+
## Paragraph
66+
A model of a paragraph.
67+
68+
### Allowed parameters
69+
<table>
70+
<tr>
71+
<td><b>contents</b></td>
72+
<td>str</td>
73+
<td><i>Paragraph contents, which make up the <a href="#section">Section</a>s.</i></td>
74+
</tr>
75+
76+
77+
</table>
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import modelspec
2+
from modelspec import field, instance_of, optional
3+
from modelspec.base_types import Base
4+
from typing import List
5+
6+
# Example showing how to create a model of a document and use it to create/serialize instances
7+
8+
9+
@modelspec.define
10+
class Paragraph(Base):
11+
"""
12+
A model of a paragraph.
13+
14+
Args:
15+
contents: Paragraph contents, which make up the :class:`Section`s.
16+
"""
17+
18+
contents: str = field(validator=instance_of(str))
19+
20+
21+
@modelspec.define
22+
class Section(Base):
23+
"""
24+
A model of a section of the :class:`Document`.
25+
Will contain one :class:`Paragraph` or more, i.e the :class:`Paragraph`(s) in the section, probably related to the :code:`title` of the `Document <#document>`_.
26+
27+
Args:
28+
id: The id of the section
29+
paragraphs: The paragraphs
30+
"""
31+
32+
id: str = field(validator=instance_of(str))
33+
paragraphs: List[Paragraph] = field(factory=list)
34+
35+
36+
@modelspec.define
37+
class Document(Base):
38+
"""
39+
A model for documents.
40+
41+
Args:
42+
id: The unique id of the document
43+
title: The document title
44+
ISBN: International Standard Book Number
45+
sections: The sections of the document
46+
"""
47+
48+
id: str = field(validator=instance_of(str))
49+
title: str = field(default=None, validator=optional(instance_of(str)))
50+
ISBN: int = field(default=None, validator=optional(instance_of(int)))
51+
sections: List[Section] = field(factory=list)
52+
53+
54+
doc = Document(id="MyBook")
55+
doc.title = "My life in Python"
56+
57+
a = Section(id="Abstract")
58+
a.paragraphs.append(Paragraph(contents="Blah blah blah"))
59+
a.paragraphs.append(Paragraph(contents="Blah2"))
60+
doc.sections.append(a)
61+
62+
c1 = Section(id="Chapter 1")
63+
doc.sections.append(c1)
64+
c1.paragraphs.append(Paragraph(contents="More..."))
65+
66+
print(doc)
67+
print(doc.sections[0].paragraphs[0].contents)
68+
print(doc.sections[0].paragraphs[1].__getattribute__("contents"))
69+
70+
doc.to_json_file("document.json")
71+
doc.to_yaml_file("document.yaml")
72+
doc.to_bson_file("document.bson")
73+
74+
print(" >> Full document details in YAML format:\n")
75+
76+
print(doc.to_yaml())
77+
78+
doc_md = doc.generate_documentation(format="markdown")
79+
80+
with open("document.md", "w") as d:
81+
d.write(doc_md)
82+
83+
84+
doc_rst = doc.generate_documentation(format="rst")
85+
86+
with open("document.rst", "w") as d:
87+
d.write(doc_rst)
88+
89+
90+
print("\n >> Generating specification in dict form...")
91+
doc_dict = doc.generate_documentation(format="dict")
92+
93+
import json
94+
import yaml
95+
import bson
96+
97+
with open("document.specification.json", "w") as d:
98+
d.write(json.dumps(doc_dict, indent=4))
99+
100+
print(" >> Generating specification in YAML...\n")
101+
102+
with open("document.specification.yaml", "w") as d:
103+
yy = yaml.dump(doc_dict, indent=4, sort_keys=False)
104+
print(yy)
105+
d.write(yy)
106+
107+
with open("document.specification.bson", "wb") as d:
108+
d.write(bson.encode(doc_dict))
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
========
2+
Document
3+
========
4+
A model for documents.
5+
6+
**Allowed parameters**
7+
8+
=============== =========== ==================================
9+
Allowed field Data Type Description
10+
=============== =========== ==================================
11+
**id** str The unique id of the document
12+
**title** str The document title
13+
**ISBN** int International Standard Book Number
14+
=============== =========== ==================================
15+
16+
**Allowed children**
17+
18+
=============== ====================== ============================
19+
Allowed child Data Type Description
20+
=============== ====================== ============================
21+
**sections** `Section <#section>`__ The sections of the document
22+
=============== ====================== ============================
23+
24+
=======
25+
Section
26+
=======
27+
A model of a section of the `Document <#document>`__. Will contain one `Paragraph <#paragraph>`__ or more, i.e the `Paragraph(s) <#paragraph>`__ in the section, probably related to the **title** of the `Document <#document>`_.
28+
29+
**Allowed parameters**
30+
31+
=============== =========== =====================
32+
Allowed field Data Type Description
33+
=============== =========== =====================
34+
**id** str The id of the section
35+
=============== =========== =====================
36+
37+
**Allowed children**
38+
39+
=============== ========================== ==============
40+
Allowed child Data Type Description
41+
=============== ========================== ==============
42+
**paragraphs** `Paragraph <#paragraph>`__ The paragraphs
43+
=============== ========================== ==============
44+
45+
=========
46+
Paragraph
47+
=========
48+
A model of a paragraph.
49+
50+
**Allowed parameters**
51+
52+
=============== =========== ==============================================================
53+
Allowed field Data Type Description
54+
=============== =========== ==============================================================
55+
**contents** str Paragraph contents, which make up the `Sections <#section>`__.
56+
=============== =========== ==============================================================
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
{
2+
"Document": {
3+
"definition": "A model for documents.",
4+
"allowed_parameters": {
5+
"id": {
6+
"type": "str",
7+
"description": "The unique id of the document"
8+
},
9+
"title": {
10+
"type": "str",
11+
"description": "The document title"
12+
},
13+
"ISBN": {
14+
"type": "int",
15+
"description": "International Standard Book Number"
16+
}
17+
},
18+
"allowed_children": {
19+
"sections": {
20+
"type": "Section",
21+
"description": "The sections of the document"
22+
}
23+
}
24+
},
25+
"Section": {
26+
"definition": "A model of a section of the :class:`Document`. Will contain one :class:`Paragraph` or more, i.e the :class:`Paragraph`(s) in the section, probably related to the :code:`title` of the `Document <#document>`_.",
27+
"allowed_parameters": {
28+
"id": {
29+
"type": "str",
30+
"description": "The id of the section"
31+
}
32+
},
33+
"allowed_children": {
34+
"paragraphs": {
35+
"type": "Paragraph",
36+
"description": "The paragraphs"
37+
}
38+
}
39+
},
40+
"Paragraph": {
41+
"definition": "A model of a paragraph.",
42+
"allowed_parameters": {
43+
"contents": {
44+
"type": "str",
45+
"description": "Paragraph contents, which make up the :class:`Section`s."
46+
}
47+
}
48+
}
49+
}

0 commit comments

Comments
 (0)