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.
@@ -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()