PlanOpticon

feat(api): add OpenAPI 3.0 spec stub for future REST API

lmata 2026-03-07 22:16 trunk
Commit 891fe17b3f71735de64ddf781b5dfc6d95c23f969f89a14abc46895f9a12f24c
--- pyproject.toml
+++ pyproject.toml
@@ -116,10 +116,11 @@
116116
[tool.ruff.lint]
117117
select = ["E", "F", "W", "I"]
118118
119119
[tool.ruff.lint.per-file-ignores]
120120
"video_processor/utils/prompt_templates.py" = ["E501"]
121
+"video_processor/api/openapi_spec.py" = ["E501"]
121122
122123
[tool.mypy]
123124
python_version = "3.10"
124125
warn_return_any = true
125126
warn_unused_configs = true
126127
127128
ADDED video_processor/api/openapi_spec.py
--- pyproject.toml
+++ pyproject.toml
@@ -116,10 +116,11 @@
116 [tool.ruff.lint]
117 select = ["E", "F", "W", "I"]
118
119 [tool.ruff.lint.per-file-ignores]
120 "video_processor/utils/prompt_templates.py" = ["E501"]
 
121
122 [tool.mypy]
123 python_version = "3.10"
124 warn_return_any = true
125 warn_unused_configs = true
126
127 DDED video_processor/api/openapi_spec.py
--- pyproject.toml
+++ pyproject.toml
@@ -116,10 +116,11 @@
116 [tool.ruff.lint]
117 select = ["E", "F", "W", "I"]
118
119 [tool.ruff.lint.per-file-ignores]
120 "video_processor/utils/prompt_templates.py" = ["E501"]
121 "video_processor/api/openapi_spec.py" = ["E501"]
122
123 [tool.mypy]
124 python_version = "3.10"
125 warn_return_any = true
126 warn_unused_configs = true
127
128 DDED video_processor/api/openapi_spec.py
--- a/video_processor/api/openapi_spec.py
+++ b/video_processor/api/openapi_spec.py
@@ -0,0 +1,183 @@
1
+"""OpenAPI 3.0 specification stub for the PlanOpticon REST API."""
2
+
3
+
4
+def get_openapi_spec() -> dict:
5
+ """Return an OpenAPI 3.0 spec dict for the planned PlanOpticon API."""
6
+ return {
7
+ "openapi": "3.0.3",
8
+ "info": {
9
+ "title": "PlanOpticon API",
10
+ "version": "0.1.0",
11
+ "description": "Video analysis and knowledge extraction REST API.",
12
+ },
13
+ "paths": {
14
+ "/analyze": {
15
+ "post": {
16
+ "summary": "Submit a video for analysis",
17
+ "operationId": "createAnalysis",
18
+ "requestBody": {
19
+ "required": True,
20
+ "content": {
21
+ "application/json": {
22
+ "schema": {
23
+ "type": "object",
24
+ "required": ["video_url"],
25
+ "properties": {
26
+ "video_url": {"type": "string", "format": "uri"},
27
+ "depth": {
28
+ "type": "string",
29
+ "enum": ["basic", "standard", "comprehensive"],
30
+ },
31
+ "focus_areas": {
32
+ "type": "array",
33
+ "items": {"type": "string"},
34
+ },
35
+ "webhook_url": {"type": "string", "format": "uri"},
36
+ "speaker_hints": {
37
+ "type": "array",
38
+ "items": {"type": "string"},
39
+ },
40
+ },
41
+ }
42
+ }
43
+ },
44
+ },
45
+ "responses": {
46
+ "202": {
47
+ "description": "Analysis job accepted",
48
+ "content": {
49
+ "application/json": {"schema": {"$ref": "#/components/schemas/Job"}}
50
+ },
51
+ }
52
+ },
53
+ }
54
+ },
55
+ "/jobs/{id}": {
56
+ "get": {
57
+ "summary": "Get analysis job status",
58
+ "operationId": "getJob",
59
+ "parameters": [
60
+ {"name": "id", "in": "path", "required": True, "schema": {"type": "string"}}
61
+ ],
62
+ "responses": {
63
+ "200": {
64
+ "description": "Job status",
65
+ "content": {
66
+ "application/json": {"schema": {"$ref": "#/components/schemas/Job"}}
67
+ },
68
+ }
69
+ },
70
+ }
71
+ },
72
+ "/knowledge-graph/{id}/entities": {
73
+ "get": {
74
+ "summary": "List entities in a knowledge graph",
75
+ "operationId": "listEntities",
76
+ "parameters": [
77
+ {
78
+ "name": "id",
79
+ "in": "path",
80
+ "required": True,
81
+ "schema": {"type": "string"},
82
+ },
83
+ {"name": "type", "in": "query", "schema": {"type": "string"}},
84
+ ],
85
+ "responses": {
86
+ "200": {
87
+ "description": "Entity list",
88
+ "content": {
89
+ "application/json": {
90
+ "schema": {
91
+ "type": "array",
92
+ "items": {"$ref": "#/components/schemas/Entity"},
93
+ }
94
+ }
95
+ },
96
+ }
97
+ },
98
+ }
99
+ },
100
+ "/knowledge-graph/{id}/relationships": {
101
+ "get": {
102
+ "summary": "List relationships in a knowledge graph",
103
+ "operationId": "listRelationships",
104
+ "parameters": [
105
+ {"name": "id", "in": "path", "required": True, "schema": {"type": "string"}}
106
+ ],
107
+ "responses": {
108
+ "200": {
109
+ "description": "Relationship list",
110
+ "content": {
111
+ "application/json": {
112
+ "schema": {
113
+ "type": "array",
114
+ "items": {"$ref": "#/components/schemas/Relationship"},
115
+ }
116
+ }
117
+ },
118
+ }
119
+ },
120
+ }
121
+ },
122
+ "/knowledge-graph/{id}/query": {
123
+ "get": {
124
+ "summary": "Query the knowledge graph with natural language",
125
+ "operationId": "queryKnowledgeGraph",
126
+ "parameters": [
127
+ {
128
+ "name": "id",
129
+ "in": "path",
130
+ "required": True,
131
+ "schema": {"type": "string"},
132
+ },
133
+ {
134
+ "name": "q",
135
+ "in": "query",
136
+ "required": True,
137
+ "schema": {"type": "string"},
138
+ },
139
+ ],
140
+ "responses": {
141
+ "200": {
142
+ "description": "Query results",
143
+ "content": {"application/json": {"schema": {"type": "object"}}},
144
+ }
145
+ },
146
+ }
147
+ },
148
+ },
149
+ "components": {
150
+ "schemas": {
151
+ "Job": {
152
+ "type": "object",
153
+ "properties": {
154
+ "id": {"type": "string"},
155
+ "status": {
156
+ "type": "string",
157
+ "enum": ["pending", "processing", "completed", "failed"],
158
+ },
159
+ "progress": {"type": "number", "format": "float"},
160
+ "created_at": {"type": "string", "format": "date-time"},
161
+ "completed_at": {"type": "string", "format": "date-time"},
162
+ "result_url": {"type": "string", "format": "uri"},
163
+ },
164
+ },
165
+ "Entity": {
166
+ "type": "object",
167
+ "properties": {
168
+ "name": {"type": "string"},
169
+ "type": {"type": "string"},
170
+ "descriptions": {"type": "array", "items": {"type": "string"}},
171
+ },
172
+ },
173
+ "Relationship": {
174
+ "type": "object",
175
+ "properties": {
176
+ "source": {"type": "string"},
177
+ "target": {"type": "string"},
178
+ "type": {"type": "string"},
179
+ },
180
+ },
181
+ }
182
+ },
183
+ }
--- a/video_processor/api/openapi_spec.py
+++ b/video_processor/api/openapi_spec.py
@@ -0,0 +1,183 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/video_processor/api/openapi_spec.py
+++ b/video_processor/api/openapi_spec.py
@@ -0,0 +1,183 @@
1 """OpenAPI 3.0 specification stub for the PlanOpticon REST API."""
2
3
4 def get_openapi_spec() -> dict:
5 """Return an OpenAPI 3.0 spec dict for the planned PlanOpticon API."""
6 return {
7 "openapi": "3.0.3",
8 "info": {
9 "title": "PlanOpticon API",
10 "version": "0.1.0",
11 "description": "Video analysis and knowledge extraction REST API.",
12 },
13 "paths": {
14 "/analyze": {
15 "post": {
16 "summary": "Submit a video for analysis",
17 "operationId": "createAnalysis",
18 "requestBody": {
19 "required": True,
20 "content": {
21 "application/json": {
22 "schema": {
23 "type": "object",
24 "required": ["video_url"],
25 "properties": {
26 "video_url": {"type": "string", "format": "uri"},
27 "depth": {
28 "type": "string",
29 "enum": ["basic", "standard", "comprehensive"],
30 },
31 "focus_areas": {
32 "type": "array",
33 "items": {"type": "string"},
34 },
35 "webhook_url": {"type": "string", "format": "uri"},
36 "speaker_hints": {
37 "type": "array",
38 "items": {"type": "string"},
39 },
40 },
41 }
42 }
43 },
44 },
45 "responses": {
46 "202": {
47 "description": "Analysis job accepted",
48 "content": {
49 "application/json": {"schema": {"$ref": "#/components/schemas/Job"}}
50 },
51 }
52 },
53 }
54 },
55 "/jobs/{id}": {
56 "get": {
57 "summary": "Get analysis job status",
58 "operationId": "getJob",
59 "parameters": [
60 {"name": "id", "in": "path", "required": True, "schema": {"type": "string"}}
61 ],
62 "responses": {
63 "200": {
64 "description": "Job status",
65 "content": {
66 "application/json": {"schema": {"$ref": "#/components/schemas/Job"}}
67 },
68 }
69 },
70 }
71 },
72 "/knowledge-graph/{id}/entities": {
73 "get": {
74 "summary": "List entities in a knowledge graph",
75 "operationId": "listEntities",
76 "parameters": [
77 {
78 "name": "id",
79 "in": "path",
80 "required": True,
81 "schema": {"type": "string"},
82 },
83 {"name": "type", "in": "query", "schema": {"type": "string"}},
84 ],
85 "responses": {
86 "200": {
87 "description": "Entity list",
88 "content": {
89 "application/json": {
90 "schema": {
91 "type": "array",
92 "items": {"$ref": "#/components/schemas/Entity"},
93 }
94 }
95 },
96 }
97 },
98 }
99 },
100 "/knowledge-graph/{id}/relationships": {
101 "get": {
102 "summary": "List relationships in a knowledge graph",
103 "operationId": "listRelationships",
104 "parameters": [
105 {"name": "id", "in": "path", "required": True, "schema": {"type": "string"}}
106 ],
107 "responses": {
108 "200": {
109 "description": "Relationship list",
110 "content": {
111 "application/json": {
112 "schema": {
113 "type": "array",
114 "items": {"$ref": "#/components/schemas/Relationship"},
115 }
116 }
117 },
118 }
119 },
120 }
121 },
122 "/knowledge-graph/{id}/query": {
123 "get": {
124 "summary": "Query the knowledge graph with natural language",
125 "operationId": "queryKnowledgeGraph",
126 "parameters": [
127 {
128 "name": "id",
129 "in": "path",
130 "required": True,
131 "schema": {"type": "string"},
132 },
133 {
134 "name": "q",
135 "in": "query",
136 "required": True,
137 "schema": {"type": "string"},
138 },
139 ],
140 "responses": {
141 "200": {
142 "description": "Query results",
143 "content": {"application/json": {"schema": {"type": "object"}}},
144 }
145 },
146 }
147 },
148 },
149 "components": {
150 "schemas": {
151 "Job": {
152 "type": "object",
153 "properties": {
154 "id": {"type": "string"},
155 "status": {
156 "type": "string",
157 "enum": ["pending", "processing", "completed", "failed"],
158 },
159 "progress": {"type": "number", "format": "float"},
160 "created_at": {"type": "string", "format": "date-time"},
161 "completed_at": {"type": "string", "format": "date-time"},
162 "result_url": {"type": "string", "format": "uri"},
163 },
164 },
165 "Entity": {
166 "type": "object",
167 "properties": {
168 "name": {"type": "string"},
169 "type": {"type": "string"},
170 "descriptions": {"type": "array", "items": {"type": "string"}},
171 },
172 },
173 "Relationship": {
174 "type": "object",
175 "properties": {
176 "source": {"type": "string"},
177 "target": {"type": "string"},
178 "type": {"type": "string"},
179 },
180 },
181 }
182 },
183 }

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button