pylode 3.5.2__tar.gz → 3.6.0__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.
Files changed (65) hide show
  1. {pylode-3.5.2 → pylode-3.6.0}/PKG-INFO +24 -20
  2. {pylode-3.5.2 → pylode-3.6.0}/README.md +22 -18
  3. {pylode-3.5.2 → pylode-3.6.0}/pylode/cli.py +14 -10
  4. {pylode-3.5.2 → pylode-3.6.0}/pylode/profiles/ontpub.py +40 -33
  5. {pylode-3.5.2 → pylode-3.6.0}/pylode/profiles/supermodel/dataset.py +2 -1
  6. {pylode-3.5.2 → pylode-3.6.0}/pylode/profiles/supermodel/html.py +35 -0
  7. {pylode-3.5.2 → pylode-3.6.0}/pylode/profiles/supermodel/model.py +3 -0
  8. {pylode-3.5.2 → pylode-3.6.0}/pylode/profiles/supermodel/query/__init__.py +55 -4
  9. {pylode-3.5.2 → pylode-3.6.0}/pylode/profiles/valpub.py +33 -20
  10. {pylode-3.5.2 → pylode-3.6.0}/pylode/profiles/vocpub.py +54 -31
  11. {pylode-3.5.2 → pylode-3.6.0}/pylode/pylode.css +67 -2
  12. pylode-3.6.0/pylode/rdf/dcterms.ttl +415 -0
  13. pylode-3.6.0/pylode/rdf/licenses.ttl +36 -0
  14. pylode-3.6.0/pylode/rdf/obo.ttl +328 -0
  15. pylode-3.6.0/pylode/rdf/ontpub.ttl +46 -0
  16. pylode-3.6.0/pylode/rdf/owl.ttl +336 -0
  17. pylode-3.6.0/pylode/rdf/prov.ttl +659 -0
  18. pylode-3.6.0/pylode/rdf/rdf.ttl +97 -0
  19. pylode-3.6.0/pylode/rdf/rdfs-mod.ttl +68 -0
  20. pylode-3.6.0/pylode/rdf/reg-statuses.ttl +88 -0
  21. pylode-3.6.0/pylode/rdf/sdo-mod.ttl +5877 -0
  22. pylode-3.6.0/pylode/rdf/shacl.ttl +1004 -0
  23. pylode-3.6.0/pylode/rdf/skos.ttl +190 -0
  24. pylode-3.6.0/pylode/rdf/void.ttl +159 -0
  25. {pylode-3.5.2 → pylode-3.6.0}/pylode/rdf_elements.py +63 -0
  26. {pylode-3.5.2 → pylode-3.6.0}/pylode/utils.py +192 -43
  27. {pylode-3.5.2 → pylode-3.6.0}/pyproject.toml +5 -2
  28. {pylode-3.5.2 → pylode-3.6.0}/pyproject.toml.orig +7 -2
  29. pylode-3.5.2/pylode/rdf/dcterms-mod.ttl +0 -869
  30. pylode-3.5.2/pylode/rdf/licenses.ttl +0 -99
  31. pylode-3.5.2/pylode/rdf/ontpub.ttl +0 -65
  32. pylode-3.5.2/pylode/rdf/owl.ttl +0 -552
  33. pylode-3.5.2/pylode/rdf/prov.ttl +0 -2465
  34. pylode-3.5.2/pylode/rdf/rdf.ttl +0 -154
  35. pylode-3.5.2/pylode/rdf/rdfs-mod.ttl +0 -109
  36. pylode-3.5.2/pylode/rdf/reg-statuses.ttl +0 -188
  37. pylode-3.5.2/pylode/rdf/sdo-mod.ttl +0 -11464
  38. pylode-3.5.2/pylode/rdf/shacl.ttl +0 -2057
  39. pylode-3.5.2/pylode/rdf/skos.ttl +0 -287
  40. pylode-3.5.2/pylode/rdf/void.ttl +0 -257
  41. {pylode-3.5.2 → pylode-3.6.0}/pylode/__init__.py +0 -0
  42. {pylode-3.5.2 → pylode-3.6.0}/pylode/__main__.py +0 -0
  43. {pylode-3.5.2 → pylode-3.6.0}/pylode/profiles/__init__.py +0 -0
  44. {pylode-3.5.2 → pylode-3.6.0}/pylode/profiles/supermodel/__init__.py +0 -0
  45. {pylode-3.5.2 → pylode-3.6.0}/pylode/profiles/supermodel/component/__init__.py +0 -0
  46. {pylode-3.5.2 → pylode-3.6.0}/pylode/profiles/supermodel/component/example.py +0 -0
  47. {pylode-3.5.2 → pylode-3.6.0}/pylode/profiles/supermodel/component/heading.py +0 -0
  48. {pylode-3.5.2 → pylode-3.6.0}/pylode/profiles/supermodel/component/link.py +0 -0
  49. {pylode-3.5.2 → pylode-3.6.0}/pylode/profiles/supermodel/component/preamble.py +0 -0
  50. {pylode-3.5.2 → pylode-3.6.0}/pylode/profiles/supermodel/component/properties_table.py +0 -0
  51. {pylode-3.5.2 → pylode-3.6.0}/pylode/profiles/supermodel/component/tooltip.py +0 -0
  52. {pylode-3.5.2 → pylode-3.6.0}/pylode/profiles/supermodel/fragment.py +0 -0
  53. {pylode-3.5.2 → pylode-3.6.0}/pylode/profiles/supermodel/loader.py +0 -0
  54. {pylode-3.5.2 → pylode-3.6.0}/pylode/profiles/supermodel/namespace.py +0 -0
  55. {pylode-3.5.2 → pylode-3.6.0}/pylode/profiles/supermodel/query/common.py +0 -0
  56. {pylode-3.5.2 → pylode-3.6.0}/pylode/profiles/supermodel/query/property_shape.py +0 -0
  57. {pylode-3.5.2 → pylode-3.6.0}/pylode/profiles/supermodel/random.py +0 -0
  58. {pylode-3.5.2 → pylode-3.6.0}/pylode/profiles/supermodel/state.py +0 -0
  59. {pylode-3.5.2 → pylode-3.6.0}/pylode/server.py +0 -0
  60. {pylode-3.5.2 → pylode-3.6.0}/pylode/static/asciidoc.css +0 -0
  61. {pylode-3.5.2 → pylode-3.6.0}/pylode/static/hierarchy.css +0 -0
  62. {pylode-3.5.2 → pylode-3.6.0}/pylode/static/hierarchy.js +0 -0
  63. {pylode-3.5.2 → pylode-3.6.0}/pylode/static/property-table-row.js +0 -0
  64. {pylode-3.5.2 → pylode-3.6.0}/pylode/static/pylode.css +0 -0
  65. {pylode-3.5.2 → pylode-3.6.0}/pylode/version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pylode
3
- Version: 3.5.2
3
+ Version: 3.6.0
4
4
  Summary: An OWL ontology documentation tool using Python, based on LODE.
5
5
  Author: Nicholas Car
6
6
  Author-email: Nicholas Car <nick@kurrawong.ai>
@@ -15,7 +15,7 @@ Requires-Dist: dominate>=2.9.1,<3
15
15
  Requires-Dist: html5lib>=1.1,<2
16
16
  Requires-Dist: httpx>=0.25.0,<1.0.0
17
17
  Requires-Dist: tqdm>=4.67.3
18
- Requires-Dist: kurra>=2.3.5
18
+ Requires-Dist: kurra>=3.0.5
19
19
  Requires-Dist: bs4>=0.0.2 ; extra == 'server'
20
20
  Requires-Dist: falcon>=4.2.0 ; extra == 'server'
21
21
  Requires-Dist: validators>=0.35.0 ; extra == 'server'
@@ -81,7 +81,7 @@ The tool can be used in multiple ways:
81
81
  ### Command line arguments
82
82
 
83
83
  ```text
84
- usage: pylode [-h] [-v] [-o OUTPUTFILE] [-c {true,false}] [-s] [-p {ontpub,vocpub,supermodel}] [-l {error,warning,info,debug}] input
84
+ usage: pylode [-h] [-v] [-o OUTPUTFILE] [-c {true,false}] [-s {true,false}] [-p {ontpub,valpub,vocpub,supermodel}] [-l {error,warning,info,debug}] input
85
85
 
86
86
  positional arguments:
87
87
  input Input file location or URL
@@ -93,9 +93,11 @@ options:
93
93
  A name you wish to assign to the output file. Will be postfixed with .html if not already added. If no output file is given, output will be printed to screen
94
94
  -c, --css {true,false}
95
95
  Whether (true) or not (false) to include CSS within an output HTML file.
96
- -s, --sort Enables sorting of the subjects in the ontology in the output
97
- -p, --profile {ontpub,vocpub,supermodel}
98
- Which profile to use to generate HTML. Must be one of 'ontpub' (https://linked.data.gov.au/def/ontpub) - for ontologies, 'vocpub' (https://linked.data.gov.au/def/vocpub) - for SKOS vocabularies, 'supermodel' - for profiles of profiles
96
+ -s, --sort {true,false}
97
+ Whether (true) or not (false) to sort ontology subjects in the output.
98
+ -p, --profile {ontpub,valpub,vocpub,supermodel}
99
+ Which profile to use to generate HTML. Must be one of 'ontpub' (https://linked.data.gov.au/def/ontpub) - for ontologies, 'valpub' (https://linked.data.gov.au/def/valpub) - for SHACL
100
+ Shapes Graphs, 'vocpub' (https://linked.data.gov.au/def/vocpub) - for SKOS vocabularies, 'supermodel' - for profiles of profiles. If omitted, the profile is inferred from the input RDF.
99
101
  -l, --loglevel {error,warning,info,debug}
100
102
  Set the logging level
101
103
  ```
@@ -108,7 +110,13 @@ options:
108
110
  python pylode examples/ontpub/minimal.ttl -o minimal.html
109
111
  ```
110
112
 
111
- for a SKOS vocabulary, indicate the `vocpub` profile:
113
+ for a SKOS vocabulary:
114
+
115
+ ```bash
116
+ python pylode examples/vocpub/GeologicSpecimenMaterialTypes.ttl -o GeologicSpecimenMaterialTypes.html
117
+ ```
118
+
119
+ for the same SKOS vocabulary with the `vocpub` being forciply selected:
112
120
 
113
121
  ```bash
114
122
  python pylode examples/vocpub/GeologicSpecimenMaterialTypes.ttl -o GeologicSpecimenMaterialTypes.html -p vocpub
@@ -118,14 +126,11 @@ python pylode examples/vocpub/GeologicSpecimenMaterialTypes.ttl -o GeologicSpeci
118
126
 
119
127
  ```bash
120
128
  docker build -t pylode:latest .
121
- ```
122
129
 
123
- ```bash
124
- docker run --mount 'type=bind,src=<ttl_directory>,target=/app/pylode/data' \
125
- pylode:latest python3.10 pylode/cli.py data/<ttl_file> -o data/<html_file>
130
+ docker run --rm -v <ttl_directory>:/data pylode:latest <ttl_file> -o <html_file>
126
131
  ```
127
132
 
128
- > Note: `<ttl_directory>` must be absolute
133
+ > Note: `<ttl_directory>` must be absolute; `<ttl_file>` and `<html_file>` are relative to it
129
134
 
130
135
  #### Via a stand-alone server
131
136
 
@@ -141,14 +146,15 @@ The active endpoint accepts the following querystring parameters:
141
146
  * `url` for the absolute URL of the ontology document that you wish to render. The server hosting that ontology document must be capable of responding to Content Negotiation,
142
147
  i.e. it must supply RDF according to an HTTP `Accept` request for `text/turtle`, `application/rdf+xml` etc.
143
148
  * `profile` for the profile to use to generate HTML. Must be one of:
144
- * `ontpub` (https://linked.data.gov.au/def/ontpub) for ontologies. This is the default if no ``profile`` is provided.
145
- * `vocpub` (https://linked.data.gov.au/def/vocpub) for SKOS vocabularies
149
+ * [`ontpub`](https://linked.data.gov.au/def/ontpub) for ontologies. This is the default if no ``profile`` is provided.
150
+ * [`vocpub`](https://linked.data.gov.au/def/vocpub) for SKOS vocabularies
151
+ * [`valpub`](https://linked.data.gov.au/def/valupub) for [SHACL](https://www.w3.org/TR/shacl/) ShapesGraphs
146
152
  * `supermodel` for profiles of profiles
147
153
  * `sort` to indicate whether subjects should be sorted in the rendered output. Must be one of:
148
154
  * `true` to sort the subjects (this is the default)
149
155
  * `false` to NOT sort the subjects
150
156
 
151
- Here's an example of use with the [AGIF Ontology](https://linked.data.gov.au/def/agrif) using the source in this repository:
157
+ Here's an example of use with the [AGRIF Ontology](https://linked.data.gov.au/def/agrif) using the source in this repository:
152
158
 
153
159
  ```bash
154
160
  http://localhost:8000/pylode?url=https://raw.githubusercontent.com/RDFLib/pyLODE/refs/heads/master/examples/ontpub/agrif.ttl
@@ -158,7 +164,7 @@ The LODE responses generated by the server can be globally customised by setting
158
164
 
159
165
  * `CSS_URL` can be set to the absolute URL of a CSS stylesheet hosted elsewhere that should be referenced by pyLODE documents
160
166
  * `FAVICON_URL` can be set to the absolute URL of a favicon image hosted elsewhere that should be referenced by pyLODE documents
161
- * `FAVICON_MIME` should be set to the MIME type of the resource at ``FAVICON_URL`` if that has been configured (e.g. ``image/png`)
167
+ * `FAVICON_MIME` should be set to the MIME type of the resource at ``FAVICON_URL`` if that has been configured (e.g. ``image/png``)
162
168
  * `GTAGID` can be set to a Google Analytics Tag ID that you would like to use for tracking requests to your server.
163
169
 
164
170
  **Launch the pyLODE server standalone from your local directory:**
@@ -224,11 +230,9 @@ Rendered examples:
224
230
 
225
231
  ## What pyLODE understands
226
232
 
227
- pyLODE understands definitional ontologies (`owl:Ontology`), classes, and properties.
228
-
229
- Supported properties can be found in `rdf_elements.py`.
233
+ pyLODE understands definitional ontologies (`owl:Ontology`), classes, properties & axioms, vocabularies (`skos:ConceptScheme`), concepts and collections and SHACL Shapes Graphs (`sh:ShapesGraph` or `owl:Ontology` when containing shapes), Node and Property Shapes.
230
234
 
231
- pyLODE deliberately does **not** translate everything in RDF to HTML, enforcing a conventional ontology documentation style. Support for new patterns can be requested via the [issue tracker](https://github.com/RDFLib/pyLODE/issues).
235
+ pyLODE will try and render all ontology/vocab annotation elements, in an order starting with those listed per type of element in `rdf_elements.py` and then anything else it finds.
232
236
 
233
237
  ### Notes on Agents
234
238
 
@@ -52,7 +52,7 @@ The tool can be used in multiple ways:
52
52
  ### Command line arguments
53
53
 
54
54
  ```text
55
- usage: pylode [-h] [-v] [-o OUTPUTFILE] [-c {true,false}] [-s] [-p {ontpub,vocpub,supermodel}] [-l {error,warning,info,debug}] input
55
+ usage: pylode [-h] [-v] [-o OUTPUTFILE] [-c {true,false}] [-s {true,false}] [-p {ontpub,valpub,vocpub,supermodel}] [-l {error,warning,info,debug}] input
56
56
 
57
57
  positional arguments:
58
58
  input Input file location or URL
@@ -64,9 +64,11 @@ options:
64
64
  A name you wish to assign to the output file. Will be postfixed with .html if not already added. If no output file is given, output will be printed to screen
65
65
  -c, --css {true,false}
66
66
  Whether (true) or not (false) to include CSS within an output HTML file.
67
- -s, --sort Enables sorting of the subjects in the ontology in the output
68
- -p, --profile {ontpub,vocpub,supermodel}
69
- Which profile to use to generate HTML. Must be one of 'ontpub' (https://linked.data.gov.au/def/ontpub) - for ontologies, 'vocpub' (https://linked.data.gov.au/def/vocpub) - for SKOS vocabularies, 'supermodel' - for profiles of profiles
67
+ -s, --sort {true,false}
68
+ Whether (true) or not (false) to sort ontology subjects in the output.
69
+ -p, --profile {ontpub,valpub,vocpub,supermodel}
70
+ Which profile to use to generate HTML. Must be one of 'ontpub' (https://linked.data.gov.au/def/ontpub) - for ontologies, 'valpub' (https://linked.data.gov.au/def/valpub) - for SHACL
71
+ Shapes Graphs, 'vocpub' (https://linked.data.gov.au/def/vocpub) - for SKOS vocabularies, 'supermodel' - for profiles of profiles. If omitted, the profile is inferred from the input RDF.
70
72
  -l, --loglevel {error,warning,info,debug}
71
73
  Set the logging level
72
74
  ```
@@ -79,7 +81,13 @@ options:
79
81
  python pylode examples/ontpub/minimal.ttl -o minimal.html
80
82
  ```
81
83
 
82
- for a SKOS vocabulary, indicate the `vocpub` profile:
84
+ for a SKOS vocabulary:
85
+
86
+ ```bash
87
+ python pylode examples/vocpub/GeologicSpecimenMaterialTypes.ttl -o GeologicSpecimenMaterialTypes.html
88
+ ```
89
+
90
+ for the same SKOS vocabulary with the `vocpub` being forciply selected:
83
91
 
84
92
  ```bash
85
93
  python pylode examples/vocpub/GeologicSpecimenMaterialTypes.ttl -o GeologicSpecimenMaterialTypes.html -p vocpub
@@ -89,14 +97,11 @@ python pylode examples/vocpub/GeologicSpecimenMaterialTypes.ttl -o GeologicSpeci
89
97
 
90
98
  ```bash
91
99
  docker build -t pylode:latest .
92
- ```
93
100
 
94
- ```bash
95
- docker run --mount 'type=bind,src=<ttl_directory>,target=/app/pylode/data' \
96
- pylode:latest python3.10 pylode/cli.py data/<ttl_file> -o data/<html_file>
101
+ docker run --rm -v <ttl_directory>:/data pylode:latest <ttl_file> -o <html_file>
97
102
  ```
98
103
 
99
- > Note: `<ttl_directory>` must be absolute
104
+ > Note: `<ttl_directory>` must be absolute; `<ttl_file>` and `<html_file>` are relative to it
100
105
 
101
106
  #### Via a stand-alone server
102
107
 
@@ -112,14 +117,15 @@ The active endpoint accepts the following querystring parameters:
112
117
  * `url` for the absolute URL of the ontology document that you wish to render. The server hosting that ontology document must be capable of responding to Content Negotiation,
113
118
  i.e. it must supply RDF according to an HTTP `Accept` request for `text/turtle`, `application/rdf+xml` etc.
114
119
  * `profile` for the profile to use to generate HTML. Must be one of:
115
- * `ontpub` (https://linked.data.gov.au/def/ontpub) for ontologies. This is the default if no ``profile`` is provided.
116
- * `vocpub` (https://linked.data.gov.au/def/vocpub) for SKOS vocabularies
120
+ * [`ontpub`](https://linked.data.gov.au/def/ontpub) for ontologies. This is the default if no ``profile`` is provided.
121
+ * [`vocpub`](https://linked.data.gov.au/def/vocpub) for SKOS vocabularies
122
+ * [`valpub`](https://linked.data.gov.au/def/valupub) for [SHACL](https://www.w3.org/TR/shacl/) ShapesGraphs
117
123
  * `supermodel` for profiles of profiles
118
124
  * `sort` to indicate whether subjects should be sorted in the rendered output. Must be one of:
119
125
  * `true` to sort the subjects (this is the default)
120
126
  * `false` to NOT sort the subjects
121
127
 
122
- Here's an example of use with the [AGIF Ontology](https://linked.data.gov.au/def/agrif) using the source in this repository:
128
+ Here's an example of use with the [AGRIF Ontology](https://linked.data.gov.au/def/agrif) using the source in this repository:
123
129
 
124
130
  ```bash
125
131
  http://localhost:8000/pylode?url=https://raw.githubusercontent.com/RDFLib/pyLODE/refs/heads/master/examples/ontpub/agrif.ttl
@@ -129,7 +135,7 @@ The LODE responses generated by the server can be globally customised by setting
129
135
 
130
136
  * `CSS_URL` can be set to the absolute URL of a CSS stylesheet hosted elsewhere that should be referenced by pyLODE documents
131
137
  * `FAVICON_URL` can be set to the absolute URL of a favicon image hosted elsewhere that should be referenced by pyLODE documents
132
- * `FAVICON_MIME` should be set to the MIME type of the resource at ``FAVICON_URL`` if that has been configured (e.g. ``image/png`)
138
+ * `FAVICON_MIME` should be set to the MIME type of the resource at ``FAVICON_URL`` if that has been configured (e.g. ``image/png``)
133
139
  * `GTAGID` can be set to a Google Analytics Tag ID that you would like to use for tracking requests to your server.
134
140
 
135
141
  **Launch the pyLODE server standalone from your local directory:**
@@ -195,11 +201,9 @@ Rendered examples:
195
201
 
196
202
  ## What pyLODE understands
197
203
 
198
- pyLODE understands definitional ontologies (`owl:Ontology`), classes, and properties.
199
-
200
- Supported properties can be found in `rdf_elements.py`.
204
+ pyLODE understands definitional ontologies (`owl:Ontology`), classes, properties & axioms, vocabularies (`skos:ConceptScheme`), concepts and collections and SHACL Shapes Graphs (`sh:ShapesGraph` or `owl:Ontology` when containing shapes), Node and Property Shapes.
201
205
 
202
- pyLODE deliberately does **not** translate everything in RDF to HTML, enforcing a conventional ontology documentation style. Support for new patterns can be requested via the [issue tracker](https://github.com/RDFLib/pyLODE/issues).
206
+ pyLODE will try and render all ontology/vocab annotation elements, in an order starting with those listed per type of element in `rdf_elements.py` and then anything else it finds.
203
207
 
204
208
  ### Notes on Agents
205
209
 
@@ -5,6 +5,7 @@ from pathlib import Path
5
5
 
6
6
  sys.path.insert(0, str(Path(__file__).absolute().parent.parent))
7
7
  from pylode import OntPub, PylodeError, Supermodel, ValPub, VocPub, __version__
8
+ from pylode.utils import select_profile
8
9
 
9
10
  parser = argparse.ArgumentParser()
10
11
 
@@ -37,8 +38,9 @@ parser.add_argument(
37
38
  parser.add_argument(
38
39
  "-s",
39
40
  "--sort",
40
- help="Enables sorting of the subjects in the ontology in the output",
41
- action="store_true",
41
+ help="Whether (true) or not (false) to sort ontology subjects in the output.",
42
+ choices=["true", "false"],
43
+ default="true",
42
44
  )
43
45
 
44
46
  parser.add_argument(
@@ -48,9 +50,10 @@ parser.add_argument(
48
50
  "'ontpub' (https://linked.data.gov.au/def/ontpub) - for ontologies, "
49
51
  "'valpub' (https://linked.data.gov.au/def/valpub) - for SHACL Shapes Graphs, "
50
52
  "'vocpub' (https://linked.data.gov.au/def/vocpub) - for SKOS vocabularies, "
51
- "'supermodel' - for profiles of profiles",
53
+ "'supermodel' - for profiles of profiles. If omitted, the profile is "
54
+ "inferred from the input RDF.",
52
55
  choices=["ontpub", "valpub", "vocpub", "supermodel"],
53
- default="ontpub",
56
+ default=None,
54
57
  )
55
58
 
56
59
  parser.add_argument(
@@ -77,17 +80,18 @@ def main():
77
80
  logger.setLevel(level=logging.DEBUG)
78
81
 
79
82
  try:
80
- sort_subjects = args.sort
81
- if args.profile == "ontpub":
83
+ sort_subjects = args.sort == "true"
84
+ profile = args.profile or select_profile(args.input)
85
+ if profile == "ontpub":
82
86
  html = OntPub(args.input, sort_subjects=sort_subjects)
83
- elif args.profile == "valpub":
87
+ elif profile == "valpub":
84
88
  html = ValPub(args.input, sort_subjects=sort_subjects)
85
- elif args.profile == "vocpub":
89
+ elif profile == "vocpub":
86
90
  html = VocPub(args.input, sort_subjects=sort_subjects)
87
- elif args.profile == "supermodel":
91
+ elif profile == "supermodel":
88
92
  html = Supermodel(args.input, sort_subjects=sort_subjects)
89
93
  else:
90
- raise ValueError(f"Unexpected profile type '{args.profile}'")
94
+ raise ValueError(f"Unexpected profile type '{profile}'")
91
95
  except PylodeError as e:
92
96
  print("ERROR: " + str(e))
93
97
  exit(1)
@@ -16,6 +16,7 @@ class OntPub:
16
16
  """
17
17
 
18
18
  def __init__(self, ontology: Union[Graph, Path, str], sort_subjects: bool = False):
19
+ self.sort_subjects = sort_subjects
19
20
  self.ont = load_ontology(ontology)
20
21
  if sort_subjects:
21
22
  self.ont = sort_ontology(self.ont)
@@ -73,14 +74,10 @@ class OntPub:
73
74
  for s_ in g.subjects(RDF.type, RDFS.Class):
74
75
  g.add((s_, RDF.type, OWL.Class))
75
76
 
76
- # # property types
77
- # for s_ in chain(
78
- # g.subjects(RDF.type, OWL.ObjectProperty),
79
- # g.subjects(RDF.type, OWL.FunctionalProperty),
80
- # g.subjects(RDF.type, OWL.DatatypeProperty),
81
- # g.subjects(RDF.type, OWL.AnnotationProperty),
82
- # ):
83
- # g.add((s_, RDF.type, RDF.Property))
77
+ # property types
78
+ for prop_type in OBJECT_PROPERTY_SUBCLASSES:
79
+ for s_ in g.subjects(RDF.type, prop_type):
80
+ g.add((s_, RDF.type, OWL.ObjectProperty))
84
81
 
85
82
  # name
86
83
  for s_, o in chain(
@@ -224,6 +221,7 @@ class OntPub:
224
221
  href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAC40lEQVRYhe2UT0hUQRzHp6Iss1B3VZKIDbbdfW9mnoi4f3zzjkJQeOgS0SEIb1EWBGGlLLu460zQPQM1unUIIjA6rfpm6ZAhHjoIRVQUFUlEbG+euTsdXG1d3VL3bVD4g+9h+L35fT/8fvN7ADgY9aHY5fpIvK82HO9ysu66wxWOzbkjcekKx0a2ALYA/n2AGi3a6ArFezcidziecQygNhhrcUficjP6PwBqtGijKxy/thnVBePHywYoDsFhl53GV8SEcsTx4usCMLUewTVpc23BNvEzm6Neyf1+KcG2vwqwUjgrOJq2JmHftwmkVBRGTvncFodnbI7vChO/FRznCmHsNM7aHM9Yk7Df5iqsLMw9sMNOK2g+jS4IEz0UJv4iuJZb2RltWnB4UZqH6ioGAgAAGe5vtiZhtzDx7OoRadLmeM7m6IRjhnLMW2Vx1bA5GhAmnhIcz6/xNj4Ujsky8UspwfayjDPjsF2Y6L7N8Vzx/BfP+KPg6LbgSqd8DnfJW2CnbaLhfH5ephpqygJYvQU4Z3P82TLRsDDhUTnmrSq+Y3N0Mg+Xldy/zwEAnLMWZ3pHpNExmfLs/t0dOdVcbT0JeKxUwFP2VljjqiE47Jp53LTXNxhsUZjerTByXWX6VZWRs/4bIQ2ACv+UAomgDzLCISNZxAxZKMhIDjLy1JfsaK+I+eGBUBNk5E2x8RogX/PdcDZUqieWTSh5D6nOVKqfhoycUmlHFFIyu5RXqf7AcQDISCpv/tqbMBqK883RtmpISRoxQyJKPgGn3wNk5NEigDFa6hslqV/Kj+FdBQD0bshIDlKSLlVcoWQo36UhR80BAMB73lulMn0EMpJTqD6qJiOt3mho/8GbkT2BZNgDB/V+RI0fkOrT3kRIVQbaDizJm2hdNbINBxwk5xAj3yEjuV9rZ1iIkgxixkLBA83mz8uCjLwoGwAx0vOnFSy5mtR4VTaAQvVORMnwZgSpzkrV/QmdE2tKe46+MQAAAABJRU5ErkJggg==",
225
222
  )
226
223
  meta(http_equiv="Content-Type", content="text/html; charset=utf-8")
224
+ meta(name="viewport", content="width=device-width, initial-scale=1")
227
225
  script(
228
226
  raw("\n" + schema_org.serialize(format="json-ld") + "\n\t"),
229
227
  type="application/ld+json",
@@ -250,30 +248,35 @@ class OntPub:
250
248
  self.ont.subjects(predicate=RDF.type, object=PROF.Profile),
251
249
  ):
252
250
  iri = s_
253
- for p_, o in self.ont.predicate_objects(s_):
254
- if p_ in ONTOLOGY_PROPS:
255
- this_onts_props[p_].append(o)
251
+ for p_, objects in ordered_subject_properties(self.ont, s_, ONTOLOGY_PROPS):
252
+ this_onts_props[p_].extend(objects)
256
253
 
257
254
  # make HTML for all props in order of ONT_PROPS
258
255
  sec = div(h1(this_onts_props[DCTERMS.title]), id="metadata", _class="section")
259
256
  sec.appendChild(h2("Metadata"))
260
257
  d = dl(div(dt(strong("IRI")), dd(code(str(iri)))))
261
- for prop in ONTOLOGY_PROPS:
262
- if prop in this_onts_props.keys():
263
- d.appendChild(
264
- prop_obj_pair_html(
265
- self.ont,
266
- self.back_onts,
267
- self.ns,
268
- "dl",
269
- prop,
270
- self.props_labeled[prop]["title"],
271
- self.props_labeled[prop]["description"],
272
- self.props_labeled[prop]["ont_title"],
273
- self.fids,
274
- this_onts_props[prop],
275
- )
258
+ ordered_props = [p for p in ONTOLOGY_PROPS if p in this_onts_props]
259
+ ordered_props.extend(
260
+ sorted((p for p in this_onts_props if p not in ONTOLOGY_PROPS), key=str)
261
+ )
262
+ for prop in ordered_props:
263
+ details = property_details(
264
+ prop, self.ont, self.back_onts, self.props_labeled
265
+ )
266
+ d.appendChild(
267
+ prop_obj_pair_html(
268
+ self.ont,
269
+ self.back_onts,
270
+ self.ns,
271
+ "dl",
272
+ prop,
273
+ details["title"],
274
+ details["description"],
275
+ details["ont_title"],
276
+ self.fids,
277
+ this_onts_props[prop],
276
278
  )
279
+ )
277
280
  sec.appendChild(d)
278
281
  self.content.appendChild(sec)
279
282
 
@@ -515,6 +518,10 @@ class OntPub:
515
518
  self.toc["namespaces"].append(("#" + prefix, prefix))
516
519
 
517
520
  def _make_toc(self):
521
+ def toc_entries(key):
522
+ entries = self.toc[key]
523
+ return sorted(entries) if self.sort_subjects else entries
524
+
518
525
  with self.doc:
519
526
  with div(id="toc"):
520
527
  h3("Table of Contents")
@@ -542,7 +549,7 @@ class OntPub:
542
549
  )
543
550
  )
544
551
  with ul(_class="second"):
545
- for c in sorted(self.toc["classes"]):
552
+ for c in toc_entries("classes"):
546
553
  li(a(c[1], href=c[0]), style="margin-left:10px;")
547
554
 
548
555
  if (
@@ -552,7 +559,7 @@ class OntPub:
552
559
  with li():
553
560
  h4(a("Properties", href="#properties"))
554
561
  with ul(_class="second"):
555
- for c in sorted(self.toc["properties"]):
562
+ for c in toc_entries("properties"):
556
563
  li(a(c[1], href=c[0]))
557
564
 
558
565
  if (
@@ -576,7 +583,7 @@ class OntPub:
576
583
  )
577
584
  )
578
585
  with ul(_class="second"):
579
- for c in sorted(self.toc["objectproperties"]):
586
+ for c in toc_entries("objectproperties"):
580
587
  li(a(c[1], href=c[0]), style="margin-left:10px;")
581
588
 
582
589
  if (
@@ -586,7 +593,7 @@ class OntPub:
586
593
  with li():
587
594
  h4(a("Datatype Properties", href="#datatypeproperties"))
588
595
  with ul(_class="second"):
589
- for c in sorted(self.toc["datatypeproperties"]):
596
+ for c in toc_entries("datatypeproperties"):
590
597
  li(a(c[1], href=c[0]))
591
598
 
592
599
  if (
@@ -596,7 +603,7 @@ class OntPub:
596
603
  with li():
597
604
  h4(a("Annotation Properties", href="#annotationproperties"))
598
605
  with ul(_class="second"):
599
- for c in sorted(self.toc["annotationproperties"]):
606
+ for c in toc_entries("annotationproperties"):
600
607
  li(a(c[1], href=c[0]))
601
608
 
602
609
  if (
@@ -606,7 +613,7 @@ class OntPub:
606
613
  with li():
607
614
  h4(a("Functional Properties", href="#functionalproperties"))
608
615
  with ul(_class="second"):
609
- for c in sorted(self.toc["functionalproperties"]):
616
+ for c in toc_entries("functionalproperties"):
610
617
  li(a(c[1], href=c[0]))
611
618
 
612
619
  if (
@@ -616,7 +623,7 @@ class OntPub:
616
623
  with li():
617
624
  h4(a("Custom Datatypes", href="#datatypes"))
618
625
  with ul(_class="second"):
619
- for c in sorted(self.toc["datatypes"]):
626
+ for c in toc_entries("datatypes"):
620
627
  li(a(c[1], href=c[0]))
621
628
 
622
629
  with li():
@@ -12,7 +12,7 @@ class Dataset(_Dataset):
12
12
  ) -> Graph:
13
13
  """Add a graph to dataset with correct context set.
14
14
 
15
- If we use self.add_graph(graph), it doesn't add the context correctly. Then if we
15
+ If we use self.add_graph(graph), it doesn't add the context correctly. Then, if we
16
16
  try and query the default graph like, self.objects(None, None), it returns nothing.
17
17
 
18
18
  This function fixes the above issue.
@@ -27,6 +27,7 @@ class Dataset(_Dataset):
27
27
  _graph = Graph(identifier=identifier)
28
28
  _graph.__iadd__(g)
29
29
  super().add_graph(_graph)
30
+
30
31
  for s, p, o in tqdm(g, desc="Adding triples", unit="triple"):
31
32
  self.add((s, p, o, _graph))
32
33
 
@@ -57,6 +57,7 @@ from pylode.profiles.supermodel.query import Query
57
57
  from pylode.utils import (
58
58
  PylodeError,
59
59
  load_ontology,
60
+ render_svg_image,
60
61
  sort_ontology,
61
62
  )
62
63
 
@@ -418,6 +419,9 @@ class Supermodel:
418
419
  with div(_class="paragraph"):
419
420
  p(cls.description)
420
421
 
422
+ for image in cls.images:
423
+ div(render_svg_image(image), _class="imageblock text-center")
424
+
421
425
  if cls.notes:
422
426
  for note in cls.notes:
423
427
  with div(_class="admonitionblock note"):
@@ -474,6 +478,33 @@ class Supermodel:
474
478
  else:
475
479
  external_link(subclass.name, subclass.iri)
476
480
 
481
+ if cls.equivalent_classes:
482
+ h5("Equivalent to")
483
+ with div(_class="sect5"):
484
+ with div(_class="ulist"):
485
+ with ul():
486
+ for equivalent_class in cls.equivalent_classes:
487
+ with li():
488
+ with p():
489
+ if (
490
+ equivalent_class.iri
491
+ in self.query.class_index
492
+ ):
493
+ fragment = make_html_fragment(
494
+ CLASS_STRING.format(
495
+ equivalent_class.iri
496
+ )
497
+ )
498
+ a(
499
+ equivalent_class.name,
500
+ href=f"#{fragment}",
501
+ )
502
+ else:
503
+ external_link(
504
+ equivalent_class.name,
505
+ equivalent_class.iri,
506
+ )
507
+
477
508
  if cls.properties:
478
509
  h5("Properties")
479
510
  self._make_component_model_class_properties(cls.properties)
@@ -495,6 +526,9 @@ class Supermodel:
495
526
  with div(_class="paragraph"):
496
527
  p(prop.description)
497
528
 
529
+ for image in prop.images:
530
+ div(render_svg_image(image), _class="imageblock text-center")
531
+
498
532
  if prop.notes:
499
533
  for note in prop.notes:
500
534
  with div(_class="admonitionblock note"):
@@ -1000,6 +1034,7 @@ class Supermodel:
1000
1034
  href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAC40lEQVRYhe2UT0hUQRzHp6Iss1B3VZKIDbbdfW9mnoi4f3zzjkJQeOgS0SEIb1EWBGGlLLu460zQPQM1unUIIjA6rfpm6ZAhHjoIRVQUFUlEbG+euTsdXG1d3VL3bVD4g+9h+L35fT/8fvN7ADgY9aHY5fpIvK82HO9ysu66wxWOzbkjcekKx0a2ALYA/n2AGi3a6ArFezcidziecQygNhhrcUficjP6PwBqtGijKxy/thnVBePHywYoDsFhl53GV8SEcsTx4usCMLUewTVpc23BNvEzm6Neyf1+KcG2vwqwUjgrOJq2JmHftwmkVBRGTvncFodnbI7vChO/FRznCmHsNM7aHM9Yk7Df5iqsLMw9sMNOK2g+jS4IEz0UJv4iuJZb2RltWnB4UZqH6ioGAgAAGe5vtiZhtzDx7OoRadLmeM7m6IRjhnLMW2Vx1bA5GhAmnhIcz6/xNj4Ujsky8UspwfayjDPjsF2Y6L7N8Vzx/BfP+KPg6LbgSqd8DnfJW2CnbaLhfH5ephpqygJYvQU4Z3P82TLRsDDhUTnmrSq+Y3N0Mg+Xldy/zwEAnLMWZ3pHpNExmfLs/t0dOdVcbT0JeKxUwFP2VljjqiE47Jp53LTXNxhsUZjerTByXWX6VZWRs/4bIQ2ACv+UAomgDzLCISNZxAxZKMhIDjLy1JfsaK+I+eGBUBNk5E2x8RogX/PdcDZUqieWTSh5D6nOVKqfhoycUmlHFFIyu5RXqf7AcQDISCpv/tqbMBqK883RtmpISRoxQyJKPgGn3wNk5NEigDFa6hslqV/Kj+FdBQD0bshIDlKSLlVcoWQo36UhR80BAMB73lulMn0EMpJTqD6qJiOt3mho/8GbkT2BZNgDB/V+RI0fkOrT3kRIVQbaDizJm2hdNbINBxwk5xAj3yEjuV9rZ1iIkgxixkLBA83mz8uCjLwoGwAx0vOnFSy5mtR4VTaAQvVORMnwZgSpzkrV/QmdE2tKe46+MQAAAABJRU5ErkJggg==",
1001
1035
  )
1002
1036
  meta(http_equiv="Content-Type", content="text/html; charset=utf-8")
1037
+ meta(name="viewport", content="width=device-width, initial-scale=1")
1003
1038
  script(
1004
1039
  raw("\n" + schema_org.serialize(format="json-ld") + "\n\t"),
1005
1040
  type="application/ld+json",
@@ -171,10 +171,12 @@ class Class:
171
171
  description: str = None
172
172
  subclasses: list["Class"] = field(default_factory=list)
173
173
  superclasses: list["Class"] = field(default_factory=list)
174
+ equivalent_classes: list["Class"] = field(default_factory=list)
174
175
  properties: dict[str, list[Property]] = field(default_factory=dict)
175
176
  examples: list[MediaObject] = field(default_factory=list)
176
177
  notes: list[Note] = field(default_factory=list)
177
178
  is_defined_by: "Ontology" = None
179
+ images: list[Literal] = field(default_factory=list)
178
180
 
179
181
  def __eq__(self, other):
180
182
  if not isinstance(other, Class):
@@ -193,6 +195,7 @@ class RDFProperty:
193
195
  super_properties: list["RDFProperty"] = field(default_factory=list)
194
196
  domain_includes: list[Class] = field(default_factory=list)
195
197
  range_includes: list[Class] = field(default_factory=list)
198
+ images: list[Literal] = field(default_factory=list)
196
199
 
197
200
 
198
201
  @dataclass