cal-docs-server 3.0.0b1__py3-none-any.whl
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.
- cal_docs_server/.gitignore +1 -0
- cal_docs_server/__init__.py +1 -0
- cal_docs_server/__main__.py +64 -0
- cal_docs_server/_version.py +4 -0
- cal_docs_server/api.py +643 -0
- cal_docs_server/async_file.py +112 -0
- cal_docs_server/auth.py +253 -0
- cal_docs_server/cache_render_index.py +106 -0
- cal_docs_server/index_docs.py +449 -0
- cal_docs_server/main.py +191 -0
- cal_docs_server/render_index.py +174 -0
- cal_docs_server/render_md.py +90 -0
- cal_docs_server/resources/__init__.py +1 -0
- cal_docs_server/resources/help.md +171 -0
- cal_docs_server/resources/index_template.html +612 -0
- cal_docs_server/resources/md_template.html +244 -0
- cal_docs_server/resources/openapi.yaml +281 -0
- cal_docs_server/version.py +38 -0
- cal_docs_server/web_server.py +217 -0
- cal_docs_server-3.0.0b1.dist-info/METADATA +12 -0
- cal_docs_server-3.0.0b1.dist-info/RECORD +24 -0
- cal_docs_server-3.0.0b1.dist-info/WHEEL +4 -0
- cal_docs_server-3.0.0b1.dist-info/entry_points.txt +2 -0
- cal_docs_server-3.0.0b1.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>Documentation</title>
|
|
7
|
+
<style>
|
|
8
|
+
* {
|
|
9
|
+
margin: 0;
|
|
10
|
+
padding: 0;
|
|
11
|
+
box-sizing: border-box;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
:root {
|
|
15
|
+
--bg-primary: #0a0f1e;
|
|
16
|
+
--bg-secondary: #111827;
|
|
17
|
+
--bg-card: #1a2332;
|
|
18
|
+
--text-primary: #f0f4f8;
|
|
19
|
+
--text-secondary: #94a3b8;
|
|
20
|
+
--text-muted: #64748b;
|
|
21
|
+
--accent-primary: #3b82f6;
|
|
22
|
+
--accent-secondary: #06b6d4;
|
|
23
|
+
--border-color: #2d3748;
|
|
24
|
+
--shadow: rgba(0, 0, 0, 0.4);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
body {
|
|
28
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
|
|
29
|
+
"Helvetica Neue", Arial, sans-serif;
|
|
30
|
+
background: linear-gradient(
|
|
31
|
+
135deg,
|
|
32
|
+
var(--bg-primary) 0%,
|
|
33
|
+
var(--bg-secondary) 100%
|
|
34
|
+
);
|
|
35
|
+
color: var(--text-primary);
|
|
36
|
+
min-height: 100vh;
|
|
37
|
+
line-height: 1.7;
|
|
38
|
+
padding: 2rem 1rem;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.container {
|
|
42
|
+
max-width: 900px;
|
|
43
|
+
margin: 0 auto;
|
|
44
|
+
background: var(--bg-card);
|
|
45
|
+
border: 1px solid var(--border-color);
|
|
46
|
+
border-radius: 1rem;
|
|
47
|
+
padding: 3rem;
|
|
48
|
+
box-shadow: 0 8px 32px var(--shadow);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
h1,
|
|
52
|
+
h2,
|
|
53
|
+
h3,
|
|
54
|
+
h4,
|
|
55
|
+
h5,
|
|
56
|
+
h6 {
|
|
57
|
+
color: var(--text-primary);
|
|
58
|
+
margin-top: 2rem;
|
|
59
|
+
margin-bottom: 1rem;
|
|
60
|
+
font-weight: 700;
|
|
61
|
+
letter-spacing: -0.5px;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
h1 {
|
|
65
|
+
font-size: 2.5rem;
|
|
66
|
+
margin-top: 0;
|
|
67
|
+
background: linear-gradient(
|
|
68
|
+
135deg,
|
|
69
|
+
var(--accent-primary),
|
|
70
|
+
var(--accent-secondary)
|
|
71
|
+
);
|
|
72
|
+
-webkit-background-clip: text;
|
|
73
|
+
-webkit-text-fill-color: transparent;
|
|
74
|
+
background-clip: text;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
h2 {
|
|
78
|
+
font-size: 2rem;
|
|
79
|
+
border-bottom: 2px solid var(--border-color);
|
|
80
|
+
padding-bottom: 0.5rem;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
h3 {
|
|
84
|
+
font-size: 1.5rem;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
h4 {
|
|
88
|
+
font-size: 1.25rem;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
p {
|
|
92
|
+
margin-bottom: 1rem;
|
|
93
|
+
color: var(--text-secondary);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
a {
|
|
97
|
+
color: var(--accent-primary);
|
|
98
|
+
text-decoration: none;
|
|
99
|
+
transition: color 0.2s ease;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
a:hover {
|
|
103
|
+
color: var(--accent-secondary);
|
|
104
|
+
text-decoration: underline;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
code {
|
|
108
|
+
background: var(--bg-secondary);
|
|
109
|
+
color: var(--accent-secondary);
|
|
110
|
+
padding: 0.2rem 0.5rem;
|
|
111
|
+
border-radius: 0.25rem;
|
|
112
|
+
font-family: "Monaco", "Courier New", monospace;
|
|
113
|
+
font-size: 0.9em;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
pre {
|
|
117
|
+
background: var(--bg-secondary);
|
|
118
|
+
border: 1px solid var(--border-color);
|
|
119
|
+
border-radius: 0.5rem;
|
|
120
|
+
padding: 1.5rem;
|
|
121
|
+
overflow-x: auto;
|
|
122
|
+
margin: 1.5rem 0;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
pre code {
|
|
126
|
+
background: transparent;
|
|
127
|
+
padding: 0;
|
|
128
|
+
color: var(--text-primary);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
ul,
|
|
132
|
+
ol {
|
|
133
|
+
margin: 1rem 0 1rem 2rem;
|
|
134
|
+
color: var(--text-secondary);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
li {
|
|
138
|
+
margin: 0.5rem 0;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
blockquote {
|
|
142
|
+
border-left: 4px solid var(--accent-primary);
|
|
143
|
+
padding-left: 1.5rem;
|
|
144
|
+
margin: 1.5rem 0;
|
|
145
|
+
color: var(--text-secondary);
|
|
146
|
+
font-style: italic;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
table {
|
|
150
|
+
width: 100%;
|
|
151
|
+
border-collapse: collapse;
|
|
152
|
+
margin: 1.5rem 0;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
th,
|
|
156
|
+
td {
|
|
157
|
+
padding: 0.75rem;
|
|
158
|
+
text-align: left;
|
|
159
|
+
border-bottom: 1px solid var(--border-color);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
th {
|
|
163
|
+
background: var(--bg-secondary);
|
|
164
|
+
color: var(--text-primary);
|
|
165
|
+
font-weight: 600;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
td {
|
|
169
|
+
color: var(--text-secondary);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
tr:hover {
|
|
173
|
+
background: var(--bg-secondary);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
hr {
|
|
177
|
+
border: none;
|
|
178
|
+
border-top: 1px solid var(--border-color);
|
|
179
|
+
margin: 2rem 0;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
img {
|
|
183
|
+
max-width: 100%;
|
|
184
|
+
height: auto;
|
|
185
|
+
border-radius: 0.5rem;
|
|
186
|
+
margin: 1rem 0;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
.back-link {
|
|
190
|
+
display: inline-flex;
|
|
191
|
+
align-items: center;
|
|
192
|
+
gap: 0.5rem;
|
|
193
|
+
margin-bottom: 2rem;
|
|
194
|
+
padding: 0.5rem 1rem;
|
|
195
|
+
background: var(--bg-secondary);
|
|
196
|
+
border: 1px solid var(--border-color);
|
|
197
|
+
border-radius: 0.5rem;
|
|
198
|
+
color: var(--text-secondary);
|
|
199
|
+
text-decoration: none;
|
|
200
|
+
font-size: 0.9rem;
|
|
201
|
+
transition: all 0.2s ease;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
.back-link:hover {
|
|
205
|
+
background: var(--accent-primary);
|
|
206
|
+
border-color: var(--accent-primary);
|
|
207
|
+
color: white;
|
|
208
|
+
text-decoration: none;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
@media (max-width: 768px) {
|
|
212
|
+
body {
|
|
213
|
+
padding: 1rem 0.5rem;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
.container {
|
|
217
|
+
padding: 1.5rem;
|
|
218
|
+
border-radius: 0.5rem;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
h1 {
|
|
222
|
+
font-size: 2rem;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
h2 {
|
|
226
|
+
font-size: 1.5rem;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
</style>
|
|
230
|
+
</head>
|
|
231
|
+
<body>
|
|
232
|
+
<div class="container">
|
|
233
|
+
<a href="/" class="back-link">
|
|
234
|
+
<svg width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
|
|
235
|
+
<path
|
|
236
|
+
fill-rule="evenodd"
|
|
237
|
+
d="M15 8a.5.5 0 0 0-.5-.5H2.707l3.147-3.146a.5.5 0 1 0-.708-.708l-4 4a.5.5 0 0 0 0 .708l4 4a.5.5 0 0 0 .708-.708L2.707 8.5H14.5A.5.5 0 0 0 15 8z" />
|
|
238
|
+
</svg>
|
|
239
|
+
Back to Index
|
|
240
|
+
</a>
|
|
241
|
+
$INSERT_DATA
|
|
242
|
+
</div>
|
|
243
|
+
</body>
|
|
244
|
+
</html>
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
openapi: 3.0.3
|
|
2
|
+
info:
|
|
3
|
+
title: CAL Docs Server API
|
|
4
|
+
description: |
|
|
5
|
+
REST API for CAL Documentation Server - manage versioned documentation.
|
|
6
|
+
|
|
7
|
+
For command-line access, install cal-docs-client: `pip install cal-docs-client`
|
|
8
|
+
version: "1.0.0"
|
|
9
|
+
contact:
|
|
10
|
+
name: Cyber Assessment Labs
|
|
11
|
+
|
|
12
|
+
servers:
|
|
13
|
+
- url: /api
|
|
14
|
+
description: API base path
|
|
15
|
+
|
|
16
|
+
paths:
|
|
17
|
+
/help:
|
|
18
|
+
get:
|
|
19
|
+
summary: Get API help
|
|
20
|
+
description: Returns human-readable API documentation as plain text
|
|
21
|
+
operationId: getHelp
|
|
22
|
+
responses:
|
|
23
|
+
"200":
|
|
24
|
+
description: Help text
|
|
25
|
+
content:
|
|
26
|
+
text/plain:
|
|
27
|
+
schema:
|
|
28
|
+
type: string
|
|
29
|
+
|
|
30
|
+
/version:
|
|
31
|
+
get:
|
|
32
|
+
summary: Get server version
|
|
33
|
+
description: Returns the product name and version number
|
|
34
|
+
operationId: getVersion
|
|
35
|
+
responses:
|
|
36
|
+
"200":
|
|
37
|
+
description: Version information
|
|
38
|
+
content:
|
|
39
|
+
application/json:
|
|
40
|
+
schema:
|
|
41
|
+
type: object
|
|
42
|
+
properties:
|
|
43
|
+
product:
|
|
44
|
+
type: string
|
|
45
|
+
example: "cal-docs-server"
|
|
46
|
+
version:
|
|
47
|
+
type: string
|
|
48
|
+
example: "2.1.0"
|
|
49
|
+
apiVersion:
|
|
50
|
+
type: string
|
|
51
|
+
description: API version for compatibility checking
|
|
52
|
+
example: "1.0"
|
|
53
|
+
required:
|
|
54
|
+
- product
|
|
55
|
+
- version
|
|
56
|
+
- apiVersion
|
|
57
|
+
|
|
58
|
+
/spec:
|
|
59
|
+
get:
|
|
60
|
+
summary: Get OpenAPI specification
|
|
61
|
+
description: Returns this OpenAPI 3.0 specification
|
|
62
|
+
operationId: getSpec
|
|
63
|
+
responses:
|
|
64
|
+
"200":
|
|
65
|
+
description: OpenAPI specification
|
|
66
|
+
content:
|
|
67
|
+
application/json:
|
|
68
|
+
schema:
|
|
69
|
+
type: object
|
|
70
|
+
|
|
71
|
+
/projects:
|
|
72
|
+
get:
|
|
73
|
+
summary: List documentation projects
|
|
74
|
+
description: Returns all documentation projects and their versions
|
|
75
|
+
operationId: listProjects
|
|
76
|
+
parameters:
|
|
77
|
+
- name: search
|
|
78
|
+
in: query
|
|
79
|
+
description: Filter projects by name (case-insensitive)
|
|
80
|
+
required: false
|
|
81
|
+
schema:
|
|
82
|
+
type: string
|
|
83
|
+
responses:
|
|
84
|
+
"200":
|
|
85
|
+
description: List of projects
|
|
86
|
+
content:
|
|
87
|
+
application/json:
|
|
88
|
+
schema:
|
|
89
|
+
type: object
|
|
90
|
+
properties:
|
|
91
|
+
projects:
|
|
92
|
+
type: array
|
|
93
|
+
items:
|
|
94
|
+
$ref: "#/components/schemas/Project"
|
|
95
|
+
count:
|
|
96
|
+
type: integer
|
|
97
|
+
description: Number of projects returned
|
|
98
|
+
|
|
99
|
+
/download/{project}/{version}:
|
|
100
|
+
get:
|
|
101
|
+
summary: Download project documentation
|
|
102
|
+
description: Downloads a project version as a .zip file
|
|
103
|
+
operationId: downloadProject
|
|
104
|
+
parameters:
|
|
105
|
+
- name: project
|
|
106
|
+
in: path
|
|
107
|
+
required: true
|
|
108
|
+
description: Project directory name
|
|
109
|
+
schema:
|
|
110
|
+
type: string
|
|
111
|
+
- name: version
|
|
112
|
+
in: path
|
|
113
|
+
required: true
|
|
114
|
+
description: Version number or "latest"
|
|
115
|
+
schema:
|
|
116
|
+
type: string
|
|
117
|
+
responses:
|
|
118
|
+
"200":
|
|
119
|
+
description: Zip file download
|
|
120
|
+
content:
|
|
121
|
+
application/zip:
|
|
122
|
+
schema:
|
|
123
|
+
type: string
|
|
124
|
+
format: binary
|
|
125
|
+
"400":
|
|
126
|
+
$ref: "#/components/responses/BadRequest"
|
|
127
|
+
"404":
|
|
128
|
+
$ref: "#/components/responses/NotFound"
|
|
129
|
+
|
|
130
|
+
/upload:
|
|
131
|
+
post:
|
|
132
|
+
summary: Upload documentation
|
|
133
|
+
description: >
|
|
134
|
+
Upload a .zip file containing documentation. Requires authentication.
|
|
135
|
+
The server determines the project and version from the uploaded filename.
|
|
136
|
+
Expected format: {project}-{version}.zip (optional suffixes: -docs, -documentation, -doc).
|
|
137
|
+
operationId: uploadDocumentation
|
|
138
|
+
security:
|
|
139
|
+
- xTokenAuth: []
|
|
140
|
+
parameters:
|
|
141
|
+
- name: X-Filename
|
|
142
|
+
in: header
|
|
143
|
+
required: false
|
|
144
|
+
description: >
|
|
145
|
+
Required for raw application/zip uploads to provide a filename, e.g.
|
|
146
|
+
my-project-1.2.3-docs.zip. Multipart uploads include the filename automatically.
|
|
147
|
+
schema:
|
|
148
|
+
type: string
|
|
149
|
+
requestBody:
|
|
150
|
+
required: true
|
|
151
|
+
content:
|
|
152
|
+
multipart/form-data:
|
|
153
|
+
schema:
|
|
154
|
+
type: object
|
|
155
|
+
properties:
|
|
156
|
+
file:
|
|
157
|
+
type: string
|
|
158
|
+
format: binary
|
|
159
|
+
description: >
|
|
160
|
+
Zip file containing documentation. The filename must be parseable as
|
|
161
|
+
{project}-{version}.zip (optional suffixes: -docs, -documentation, -doc).
|
|
162
|
+
required:
|
|
163
|
+
- file
|
|
164
|
+
application/zip:
|
|
165
|
+
schema:
|
|
166
|
+
type: string
|
|
167
|
+
format: binary
|
|
168
|
+
responses:
|
|
169
|
+
"201":
|
|
170
|
+
description: Upload successful
|
|
171
|
+
content:
|
|
172
|
+
application/json:
|
|
173
|
+
schema:
|
|
174
|
+
type: object
|
|
175
|
+
properties:
|
|
176
|
+
success:
|
|
177
|
+
type: boolean
|
|
178
|
+
message:
|
|
179
|
+
type: string
|
|
180
|
+
project:
|
|
181
|
+
type: string
|
|
182
|
+
version:
|
|
183
|
+
type: string
|
|
184
|
+
directory:
|
|
185
|
+
type: string
|
|
186
|
+
description: Directory name created under the docs root
|
|
187
|
+
url:
|
|
188
|
+
type: string
|
|
189
|
+
description: URL to the uploaded documentation (may be absolute if base_url configured)
|
|
190
|
+
files_extracted:
|
|
191
|
+
type: integer
|
|
192
|
+
"400":
|
|
193
|
+
$ref: "#/components/responses/BadRequest"
|
|
194
|
+
"401":
|
|
195
|
+
$ref: "#/components/responses/Unauthorized"
|
|
196
|
+
"403":
|
|
197
|
+
$ref: "#/components/responses/Forbidden"
|
|
198
|
+
|
|
199
|
+
components:
|
|
200
|
+
schemas:
|
|
201
|
+
Project:
|
|
202
|
+
type: object
|
|
203
|
+
properties:
|
|
204
|
+
name:
|
|
205
|
+
type: string
|
|
206
|
+
description: Display name of the project
|
|
207
|
+
directory_name:
|
|
208
|
+
type: string
|
|
209
|
+
description: Directory name (used in URLs)
|
|
210
|
+
description:
|
|
211
|
+
type: string
|
|
212
|
+
description: Project description
|
|
213
|
+
versions:
|
|
214
|
+
type: array
|
|
215
|
+
items:
|
|
216
|
+
$ref: "#/components/schemas/Version"
|
|
217
|
+
logo_ref:
|
|
218
|
+
type: string
|
|
219
|
+
nullable: true
|
|
220
|
+
description: Path to project logo
|
|
221
|
+
latest_version_dir:
|
|
222
|
+
type: string
|
|
223
|
+
nullable: true
|
|
224
|
+
description: Directory of the latest stable version
|
|
225
|
+
|
|
226
|
+
Version:
|
|
227
|
+
type: object
|
|
228
|
+
properties:
|
|
229
|
+
version:
|
|
230
|
+
type: string
|
|
231
|
+
description: Version string
|
|
232
|
+
directory_name:
|
|
233
|
+
type: string
|
|
234
|
+
description: Directory name for this version
|
|
235
|
+
url:
|
|
236
|
+
type: string
|
|
237
|
+
description: URL to browse this version
|
|
238
|
+
download_url:
|
|
239
|
+
type: string
|
|
240
|
+
description: URL to download this version as a zip
|
|
241
|
+
|
|
242
|
+
Error:
|
|
243
|
+
type: object
|
|
244
|
+
properties:
|
|
245
|
+
error:
|
|
246
|
+
type: string
|
|
247
|
+
message:
|
|
248
|
+
type: string
|
|
249
|
+
|
|
250
|
+
responses:
|
|
251
|
+
BadRequest:
|
|
252
|
+
description: Bad request
|
|
253
|
+
content:
|
|
254
|
+
application/json:
|
|
255
|
+
schema:
|
|
256
|
+
$ref: "#/components/schemas/Error"
|
|
257
|
+
NotFound:
|
|
258
|
+
description: Resource not found
|
|
259
|
+
content:
|
|
260
|
+
application/json:
|
|
261
|
+
schema:
|
|
262
|
+
$ref: "#/components/schemas/Error"
|
|
263
|
+
Unauthorized:
|
|
264
|
+
description: Authentication required
|
|
265
|
+
content:
|
|
266
|
+
application/json:
|
|
267
|
+
schema:
|
|
268
|
+
$ref: "#/components/schemas/Error"
|
|
269
|
+
Forbidden:
|
|
270
|
+
description: Permission denied
|
|
271
|
+
content:
|
|
272
|
+
application/json:
|
|
273
|
+
schema:
|
|
274
|
+
$ref: "#/components/schemas/Error"
|
|
275
|
+
|
|
276
|
+
securitySchemes:
|
|
277
|
+
xTokenAuth:
|
|
278
|
+
type: apiKey
|
|
279
|
+
in: header
|
|
280
|
+
name: X-Token
|
|
281
|
+
description: API token authentication
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# ----------------------------------------------------------------------------------------
|
|
2
|
+
# version
|
|
3
|
+
# -------
|
|
4
|
+
#
|
|
5
|
+
# Version string handling - imports from generated _version.py at build time,
|
|
6
|
+
# falls back to "DEV" when not built.
|
|
7
|
+
#
|
|
8
|
+
# License
|
|
9
|
+
# -------
|
|
10
|
+
# MIT License - Copyright 2025-2026 Cyber Assessment Labs
|
|
11
|
+
#
|
|
12
|
+
# Authors
|
|
13
|
+
# -------
|
|
14
|
+
# bena
|
|
15
|
+
#
|
|
16
|
+
# Version History
|
|
17
|
+
# ---------------
|
|
18
|
+
# Nov 2025 - Created
|
|
19
|
+
# Feb 2026 - Switched to _version.py pattern
|
|
20
|
+
# ----------------------------------------------------------------------------------------
|
|
21
|
+
|
|
22
|
+
# ----------------------------------------------------------------------------------------
|
|
23
|
+
# Version
|
|
24
|
+
# ----------------------------------------------------------------------------------------
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _get_version() -> str:
|
|
28
|
+
try:
|
|
29
|
+
# fmt: off
|
|
30
|
+
from ._version import __version__ as _v # pyright: ignore[reportMissingImports,reportUnknownVariableType] # noqa: I001
|
|
31
|
+
# fmt: on
|
|
32
|
+
|
|
33
|
+
return str(_v) # pyright: ignore[reportUnknownArgumentType]
|
|
34
|
+
except ImportError:
|
|
35
|
+
return "DEV"
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
VERSION_STR: str = _get_version()
|