elwig-backend: Add /openapi.json
This commit is contained in:
7
.gitignore
vendored
7
.gitignore
vendored
@ -1,4 +1,3 @@
|
|||||||
**
|
.idea
|
||||||
!src/
|
*.sql
|
||||||
!.gitignore
|
*.sqlite3
|
||||||
!README.md
|
|
||||||
|
@ -19,6 +19,399 @@ CNX: sqlite3.Cursor
|
|||||||
USER_FILE: str
|
USER_FILE: str
|
||||||
|
|
||||||
|
|
||||||
|
OPEN_API_DOC: str = '''{
|
||||||
|
"openapi": "3.1.0",
|
||||||
|
"info": {
|
||||||
|
"title": "Elwig API",
|
||||||
|
"summary": "Elektronische Winzergenossenschaftsverwaltung (\\"Electronic Management for Vintners'/Winemakers' Cooperatives\\")",
|
||||||
|
"description": "",
|
||||||
|
"contact": {"email": "contact@necronda.net"},
|
||||||
|
"version": "0.0.1"
|
||||||
|
},
|
||||||
|
"servers": [{
|
||||||
|
"url": "https://wgm.elwig.at/elwig/api/v1",
|
||||||
|
"description": "WG Matzen"
|
||||||
|
}],
|
||||||
|
"components": {"securitySchemes": {"basicAuth": {"type": "http", "scheme": "basic"}}},
|
||||||
|
"security": [{"basicAuth": []}],
|
||||||
|
"paths": {
|
||||||
|
"/wine/varieties": {
|
||||||
|
"get": {
|
||||||
|
"tags": ["Base Data"],
|
||||||
|
"summary": "Weinsorten",
|
||||||
|
"parameters": [
|
||||||
|
{"in": "query", "name": "limit", "schema": {"type": "integer"}, "required": false},
|
||||||
|
{"in": "query", "name": "offset", "schema": {"type": "integer"}, "required": false}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Success",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["filters", "total", "offset", "limit", "data"],
|
||||||
|
"properties": {
|
||||||
|
"filters": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {"type": "object", "required": ["filter"], "properties": {"filter": {"type": "string"}}},
|
||||||
|
"description": "Applied filters"
|
||||||
|
},
|
||||||
|
"total": {"type": "integer", "description": "Total number of wine varieties in the database"},
|
||||||
|
"offset": {"type": "integer", "description": "Applied offset"},
|
||||||
|
"limit": {"oneOf": [{"type": "integer"}, {"type": "null"}], "description": "Applied limit"},
|
||||||
|
"data": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["sortid", "type", "name"],
|
||||||
|
"properties": {
|
||||||
|
"sortid": {"type": "string"},
|
||||||
|
"type": {"type": "string", "enum": ["R", "W"]},
|
||||||
|
"name": {"type": "string"},
|
||||||
|
"comment": {"type": "string"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"examples": {
|
||||||
|
"simple": {
|
||||||
|
"value": {"filters": [], "total": 4, "offset": 0, "limit": null, "data": [
|
||||||
|
{"sortid": "BL", "type": "R", "name": "Blauburger", "comment": null},
|
||||||
|
{"sortid": "GV", "type": "W", "name": "Grüner Veltliner", "comment": "Weißgipfler"},
|
||||||
|
{"sortid": "WR", "type": "W", "name": "Welschriesling", "comment": null},
|
||||||
|
{"sortid": "ZW", "type": "R", "name": "Zweigelt", "comment": "Blauer Zweigelt, Rotburger"}
|
||||||
|
]}
|
||||||
|
},
|
||||||
|
"limit": {
|
||||||
|
"value": {"filters": [], "total": 4, "offset": 0, "limit": 2, "data": [
|
||||||
|
{"sortid": "BL", "type": "R", "name": "Blauburger", "comment": null},
|
||||||
|
{"sortid": "GV", "type": "W", "name": "Grüner Veltliner", "comment": "Weißgipfler"}
|
||||||
|
]}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {"description": "Bad Request", "content": {"application/json": {"schema": {"type": "object", "required": ["message"], "properties": {"message": {"oneOf": [{"type": "string"}, {"type": "null"}]}}}, "examples": {"simple": {"value": {"message": "Invalid integer value in query"}}}}}},
|
||||||
|
"401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"type": "object", "required": ["message"], "properties": {"message": {"oneOf": [{"type": "string"}, {"type": "null"}]}}}, "examples": {"simple": {"value": {"message": "Unauthorized"}}}}}},
|
||||||
|
"500": {"description": "Internal Server Error", "content": {"application/json": {"schema": {"type": "object", "required": ["message"], "properties": {"message": {"oneOf": [{"type": "string"}, {"type": "null"}]}}}, "examples": {"simple": {"value": {"message": "Unknown error"}}}}}}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/wine/quality_levels": {
|
||||||
|
"get": {
|
||||||
|
"tags": ["Base Data"],
|
||||||
|
"summary": "Qualitätsstufen",
|
||||||
|
"parameters": [
|
||||||
|
{"in": "query", "name": "limit", "schema": {"type": "integer"}, "required": false},
|
||||||
|
{"in": "query", "name": "offset", "schema": {"type": "integer"}, "required": false}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Success",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["filters", "total", "offset", "limit", "data"],
|
||||||
|
"properties": {
|
||||||
|
"filters": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {"type": "object", "required": ["filter"], "properties": {"filter": {"type": "string"}}},
|
||||||
|
"description": "Applied filters"
|
||||||
|
},
|
||||||
|
"total": {"type": "integer", "description": "Total number of wine quality levels in the database"},
|
||||||
|
"offset": {"type": "integer", "description": "Applied offset"},
|
||||||
|
"limit": {"oneOf": [{"type": "integer"}, {"type": "null"}], "description": "Applied limit"},
|
||||||
|
"data": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["qualid", "name"],
|
||||||
|
"properties": {
|
||||||
|
"qualid": {"type": "string"},
|
||||||
|
"name": {"type": "string"},
|
||||||
|
"min_kmw": {"oneOf": [{"type": "number"}, {"type": "null"}]},
|
||||||
|
"is_predicate": {"type": "boolean"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"examples": {
|
||||||
|
"simple": {
|
||||||
|
"value": {"filters": [], "total": 10, "offset": 0, "limit": null, "data": [
|
||||||
|
{"qualid": "WEI", "name": "Wein", "min_kmw": null, "is_predicate": false},
|
||||||
|
{"qualid": "RSW", "name": "Rebsortenwein", "min_kmw": 10.6, "is_predicate": false},
|
||||||
|
{"qualid": "LDW", "name": "Landwein", "min_kmw": 14.0, "is_predicate": false},
|
||||||
|
{"qualid": "QUW", "name": "Qualitätswein", "min_kmw": 15.0, "is_predicate": false},
|
||||||
|
{"qualid": "KAB", "name": "Kabinett", "min_kmw": 17.0, "is_predicate": false},
|
||||||
|
{"qualid": "SPL", "name": "Spätlese", "min_kmw": 19.0, "is_predicate": true},
|
||||||
|
{"qualid": "AUL", "name": "Auslese", "min_kmw": 21.0, "is_predicate": true},
|
||||||
|
{"qualid": "BAL", "name": "Beerenauslese", "min_kmw": 25.0, "is_predicate": true},
|
||||||
|
{"qualid": "TBA", "name": "Trockenbeerenauslese", "min_kmw": 30.0, "is_predicate": true},
|
||||||
|
{"qualid": "DAC", "name": "DAC", "min_kmw": 15.0, "is_predicate": true}
|
||||||
|
]}
|
||||||
|
},
|
||||||
|
"limit": {
|
||||||
|
"value": {"filters": [], "total": 10, "offset": 0, "limit": 4, "data": [
|
||||||
|
{"qualid": "WEI", "name": "Wein", "min_kmw": null, "is_predicate": false},
|
||||||
|
{"qualid": "RSW", "name": "Rebsortenwein", "min_kmw": 10.6, "is_predicate": false},
|
||||||
|
{"qualid": "LDW", "name": "Landwein", "min_kmw": 14.0, "is_predicate": false},
|
||||||
|
{"qualid": "QUW", "name": "Qualitätswein", "min_kmw": 15.0, "is_predicate": false}
|
||||||
|
]}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {"description": "Bad Request", "content": {"application/json": {"schema": {"type": "object", "required": ["message"], "properties": {"message": {"oneOf": [{"type": "string"}, {"type": "null"}]}}}, "examples": {"simple": {"value": {"message": "Invalid integer value in query"}}}}}},
|
||||||
|
"401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"type": "object", "required": ["message"], "properties": {"message": {"oneOf": [{"type": "string"}, {"type": "null"}]}}}, "examples": {"simple": {"value": {"message": "Unauthorized"}}}}}},
|
||||||
|
"500": {"description": "Internal Server Error", "content": {"application/json": {"schema": {"type": "object", "required": ["message"], "properties": {"message": {"oneOf": [{"type": "string"}, {"type": "null"}]}}}, "examples": {"simple": {"value": {"message": "Unknown error"}}}}}}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/wine/attributes": {
|
||||||
|
"get": {
|
||||||
|
"tags": ["Client Base Data"],
|
||||||
|
"summary": "(Sorten-)Attribute",
|
||||||
|
"parameters": [
|
||||||
|
{"in": "query", "name": "limit", "schema": {"type": "integer"}, "required": false},
|
||||||
|
{"in": "query", "name": "offset", "schema": {"type": "integer"}, "required": false}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Success",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["filters", "total", "offset", "limit", "data"],
|
||||||
|
"properties": {
|
||||||
|
"filters": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {"type": "object", "required": ["filter"], "properties": {"filter": {"type": "string"}}},
|
||||||
|
"description": "Applied filters"
|
||||||
|
},
|
||||||
|
"total": {"type": "integer", "description": "Total number of wine attributes in the database"},
|
||||||
|
"offset": {"type": "integer", "description": "Applied offset"},
|
||||||
|
"limit": {"oneOf": [{"type": "integer"}, {"type": "null"}], "description": "Applied limit"},
|
||||||
|
"data": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["attrid", "name"],
|
||||||
|
"properties": {
|
||||||
|
"attrid": {"type": "string"},
|
||||||
|
"name": {"type": "string"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"examples": {
|
||||||
|
"simple": {
|
||||||
|
"value": {"filters": [], "total": 3, "offset": 0, "limit": null, "data": [
|
||||||
|
{"attrid": "S", "name": "Saft"},
|
||||||
|
{"attrid": "Z", "name": "Sekt"},
|
||||||
|
{"attrid": "D", "name": "DAC"}
|
||||||
|
]}
|
||||||
|
},
|
||||||
|
"limit": {
|
||||||
|
"value": {"filters": [], "total": 3, "offset": 0, "limit": 1, "data": [
|
||||||
|
{"attrid": "S", "name": "Saft"}
|
||||||
|
]}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {"description": "Bad Request", "content": {"application/json": {"schema": {"type": "object", "required": ["message"], "properties": {"message": {"oneOf": [{"type": "string"}, {"type": "null"}]}}}, "examples": {"simple": {"value": {"message": "Invalid integer value in query"}}}}}},
|
||||||
|
"401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"type": "object", "required": ["message"], "properties": {"message": {"oneOf": [{"type": "string"}, {"type": "null"}]}}}, "examples": {"simple": {"value": {"message": "Unauthorized"}}}}}},
|
||||||
|
"500": {"description": "Internal Server Error", "content": {"application/json": {"schema": {"type": "object", "required": ["message"], "properties": {"message": {"oneOf": [{"type": "string"}, {"type": "null"}]}}}, "examples": {"simple": {"value": {"message": "Unknown error"}}}}}}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/wine/cultivations": {
|
||||||
|
"get": {
|
||||||
|
"tags": ["Client Base Data"],
|
||||||
|
"summary": "Bewirtschaftungsarten",
|
||||||
|
"parameters": [
|
||||||
|
{"in": "query", "name": "limit", "schema": {"type": "integer"}, "required": false},
|
||||||
|
{"in": "query", "name": "offset", "schema": {"type": "integer"}, "required": false}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Success",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["filters", "total", "offset", "limit", "data"],
|
||||||
|
"properties": {
|
||||||
|
"filters": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {"type": "object", "required": ["filter"], "properties": {"filter": {"type": "string"}}},
|
||||||
|
"description": "Applied filters"
|
||||||
|
},
|
||||||
|
"total": {"type": "integer", "description": "Total number of wine cultivations in the database"},
|
||||||
|
"offset": {"type": "integer", "description": "Applied offset"},
|
||||||
|
"limit": {"oneOf": [{"type": "integer"}, {"type": "null"}], "description": "Applied limit"},
|
||||||
|
"data": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["cultid", "name"],
|
||||||
|
"properties": {
|
||||||
|
"cultid": {"type": "string"},
|
||||||
|
"name": {"type": "string"},
|
||||||
|
"description": {"oneOf": [{"type": "string"}, {"type": "null"}]}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"examples": {
|
||||||
|
"simple": {
|
||||||
|
"value": {"filters": [], "total": 2, "offset": 0, "limit": null, "data": [
|
||||||
|
{"cultid": "KIP", "name": "KIP", "description": "Kontrollierte Integrierte Produktion"},
|
||||||
|
{"cultid": "B", "name": "Bio", "description": "AT-BIO-302"}
|
||||||
|
]}
|
||||||
|
},
|
||||||
|
"limit": {
|
||||||
|
"value": {"filters": [], "total": 2, "offset": 0, "limit": 1, "data": [
|
||||||
|
{"cultid": "KIP", "name": "KIP", "description": "Kontrollierte Integrierte Produktion"}
|
||||||
|
]}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {"description": "Bad Request", "content": {"application/json": {"schema": {"type": "object", "required": ["message"], "properties": {"message": {"oneOf": [{"type": "string"}, {"type": "null"}]}}}, "examples": {"simple": {"value": {"message": "Invalid integer value in query"}}}}}},
|
||||||
|
"401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"type": "object", "required": ["message"], "properties": {"message": {"oneOf": [{"type": "string"}, {"type": "null"}]}}}, "examples": {"simple": {"value": {"message": "Unauthorized"}}}}}},
|
||||||
|
"500": {"description": "Internal Server Error", "content": {"application/json": {"schema": {"type": "object", "required": ["message"], "properties": {"message": {"oneOf": [{"type": "string"}, {"type": "null"}]}}}, "examples": {"simple": {"value": {"message": "Unknown error"}}}}}}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/modifiers": {
|
||||||
|
"get": {
|
||||||
|
"tags": ["Client Base Data"],
|
||||||
|
"summary": "Zu-/Abschläge",
|
||||||
|
"parameters": [
|
||||||
|
{"in": "query", "name": "limit", "schema": {"type": "integer"}, "required": false},
|
||||||
|
{"in": "query", "name": "offset", "schema": {"type": "integer"}, "required": false},
|
||||||
|
{"in": "query", "name": "filters", "schema": {"type": "string", "pattern": "^year=[0-9]+(;[0-9]+)*$"}, "required": false}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Success",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["filters", "total", "offset", "limit", "data"],
|
||||||
|
"properties": {
|
||||||
|
"filters": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {"type": "object", "required": ["filter"], "properties": {"filter": {"type": "string"}}},
|
||||||
|
"description": "Applied filters"
|
||||||
|
},
|
||||||
|
"total": {"type": "integer", "description": "Total number of modifiers in the database (on which the filters apply to)"},
|
||||||
|
"offset": {"type": "integer", "description": "Applied offset"},
|
||||||
|
"limit": {"oneOf": [{"type": "integer"}, {"type": "null"}], "description": "Applied limit"},
|
||||||
|
"data": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["year", "modid", "name"],
|
||||||
|
"properties": {
|
||||||
|
"year": {"type": "integer"},
|
||||||
|
"modid": {"type": "string"},
|
||||||
|
"name": {"type": "string"},
|
||||||
|
"ordering": {"type": "integer"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"examples": {
|
||||||
|
"filter": {
|
||||||
|
"value": {"filters": [{"filter": "year=2020"}], "total": 4, "offset": 0, "limit": null, "data": [
|
||||||
|
{"year": 2020, "modid": "A", "name": "Klasse A", "ordering": 1},
|
||||||
|
{"year": 2020, "modid": "B", "name": "Klasse B", "ordering": 2},
|
||||||
|
{"year": 2020, "modid": "C", "name": "Klasse C", "ordering": 3},
|
||||||
|
{"year": 2020, "modid": "D", "name": "Klasse D", "ordering": 4}
|
||||||
|
]}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {"description": "Bad Request", "content": {"application/json": {"schema": {"type": "object", "required": ["message"], "properties": {"message": {"oneOf": [{"type": "string"}, {"type": "null"}]}}}, "examples": {"simple": {"value": {"message": "Invalid filter"}}}}}},
|
||||||
|
"401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"type": "object", "required": ["message"], "properties": {"message": {"oneOf": [{"type": "string"}, {"type": "null"}]}}}, "examples": {"simple": {"value": {"message": "Unauthorized"}}}}}},
|
||||||
|
"500": {"description": "Internal Server Error", "content": {"application/json": {"schema": {"type": "object", "required": ["message"], "properties": {"message": {"oneOf": [{"type": "string"}, {"type": "null"}]}}}, "examples": {"simple": {"value": {"message": "Unknown error"}}}}}}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/delivery_schedules": {
|
||||||
|
"get": {
|
||||||
|
"tags": ["Delivery Schedules"],
|
||||||
|
"summary": "Lesepläne",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Success",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["filters", "total", "offset", "limit", "data"],
|
||||||
|
"properties": {
|
||||||
|
"filters": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {"type": "object", "required": ["filter"], "properties": {"filter": {"type": "string"}}},
|
||||||
|
"description": "Applied filters"
|
||||||
|
},
|
||||||
|
"total": {"type": "integer", "description": "Total number of delivery schedules in the database (on which the filters apply to)"},
|
||||||
|
"offset": {"type": "integer", "description": "Applied offset"},
|
||||||
|
"limit": {"oneOf": [{"type": "integer"}, {"type": "null"}], "description": "Applied limit"},
|
||||||
|
"data": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["year", "dsnr", "date", "branch", "description", "max_weight", "announced_weight", "delivered_weight"],
|
||||||
|
"properties": {
|
||||||
|
"year": {"type": "integer"},
|
||||||
|
"dsnr": {"type": "integer"},
|
||||||
|
"date": {"type": "string", "format": "date"},
|
||||||
|
"branch": {"type": "object", "required": ["zwstid", "name"], "properties": {"zwstid": {"type": "string"}, "name": {"type": "string"}}},
|
||||||
|
"description": {"type": "string"},
|
||||||
|
"is_cancelled": {"type": "boolean"},
|
||||||
|
"max_weight": {"oneOf": [{"type": "integer"}, {"type": "null"}]},
|
||||||
|
"announced_weight": {"oneOf": [{"type": "integer"}, {"type": "null"}]},
|
||||||
|
"delivered_weight": {"oneOf": [{"type": "integer"}, {"type": "null"}]},
|
||||||
|
"announcement_from": {"oneOf": [{"type": "string", "format": "date-time"}, {"type": "null"}]},
|
||||||
|
"announcement_to": {"oneOf": [{"type": "string", "format": "date-time"}, {"type": "null"}]}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {"description": "Bad Request", "content": {"application/json": {"schema": {"type": "object", "required": ["message"], "properties": {"message": {"oneOf": [{"type": "string"}, {"type": "null"}]}}}, "examples": {"simple": {"value": {"message": "Invalid filter"}}}}}},
|
||||||
|
"401": {"description": "Unauthorized", "content": {"application/json": {"schema": {"type": "object", "required": ["message"], "properties": {"message": {"oneOf": [{"type": "string"}, {"type": "null"}]}}}, "examples": {"simple": {"value": {"message": "Unauthorized"}}}}}},
|
||||||
|
"500": {"description": "Internal Server Error", "content": {"application/json": {"schema": {"type": "object", "required": ["message"], "properties": {"message": {"oneOf": [{"type": "string"}, {"type": "null"}]}}}, "examples": {"simple": {"value": {"message": "Unknown error"}}}}}}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'''
|
||||||
|
|
||||||
|
|
||||||
class BadRequestError(Exception):
|
class BadRequestError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -97,13 +490,15 @@ def get_delivery_schedule_filter_clauses(filters: list[Filter]) -> list[str]:
|
|||||||
|
|
||||||
|
|
||||||
class ElwigApi(BaseHTTPRequestHandler):
|
class ElwigApi(BaseHTTPRequestHandler):
|
||||||
def send(self, data: str, status_code: int = 200):
|
def send(self, data: str, status_code: int = 200, url: str = None):
|
||||||
raw = data.encode('utf-8')
|
raw = data.encode('utf-8')
|
||||||
self.send_response(status_code)
|
self.send_response(status_code)
|
||||||
self.send_header('Access-Control-Allow-Origin', '*')
|
self.send_header('Access-Control-Allow-Origin', '*')
|
||||||
self.send_header('Access-Control-Allow-Headers', 'Authorization')
|
self.send_header('Access-Control-Allow-Headers', 'Authorization')
|
||||||
self.send_header('Access-Control-Allow-Methods', 'HEAD, GET, OPTIONS')
|
self.send_header('Access-Control-Allow-Methods', 'HEAD, GET, OPTIONS')
|
||||||
if status_code == 401:
|
if 300 <= status_code < 400 and status_code != 304:
|
||||||
|
self.send_header('Location', url)
|
||||||
|
elif status_code == 401:
|
||||||
self.send_header('WWW-Authenticate', 'Basic realm=Elwig')
|
self.send_header('WWW-Authenticate', 'Basic realm=Elwig')
|
||||||
if self.headers.get('Accept-Encoding') and len(data) > 64:
|
if self.headers.get('Accept-Encoding') and len(data) > 64:
|
||||||
accept_encoding = [e.strip() for e in self.headers.get('Accept-Encoding').split(',')]
|
accept_encoding = [e.strip() for e in self.headers.get('Accept-Encoding').split(',')]
|
||||||
@ -119,6 +514,9 @@ class ElwigApi(BaseHTTPRequestHandler):
|
|||||||
def error(self, status_code: int, message: str = None):
|
def error(self, status_code: int, message: str = None):
|
||||||
self.send(f'{{"message":{jdmp(message)}}}\n', status_code=status_code)
|
self.send(f'{{"message":{jdmp(message)}}}\n', status_code=status_code)
|
||||||
|
|
||||||
|
def see_other(self, url: str):
|
||||||
|
self.send(f'{{"url": {jdmp(url)}}}\n', status_code=303, url=url)
|
||||||
|
|
||||||
def authorize(self) -> (str or None, str or None):
|
def authorize(self) -> (str or None, str or None):
|
||||||
try:
|
try:
|
||||||
auth = self.headers.get('Authorization')
|
auth = self.headers.get('Authorization')
|
||||||
@ -268,6 +666,14 @@ class ElwigApi(BaseHTTPRequestHandler):
|
|||||||
|
|
||||||
def do_GET(self):
|
def do_GET(self):
|
||||||
try:
|
try:
|
||||||
|
if self.path == '/':
|
||||||
|
openapi_json = f'https://{self.headers.get("Host", "localhost")}/elwig/api/v1/openapi.json'
|
||||||
|
self.see_other(f'https://validator.swagger.io/?url={openapi_json}')
|
||||||
|
return
|
||||||
|
elif self.path == '/openapi.json':
|
||||||
|
self.send(OPEN_API_DOC)
|
||||||
|
return
|
||||||
|
|
||||||
username, role = self.authorize()
|
username, role = self.authorize()
|
||||||
if not username or not role:
|
if not username or not role:
|
||||||
return
|
return
|
||||||
@ -279,8 +685,11 @@ class ElwigApi(BaseHTTPRequestHandler):
|
|||||||
path, query = parts[0], {urllib.parse.unquote(s[0]): urllib.parse.unquote(s[-1])
|
path, query = parts[0], {urllib.parse.unquote(s[0]): urllib.parse.unquote(s[-1])
|
||||||
for s in [p.split('=', 1) for p in parts[1].split('&')]}
|
for s in [p.split('=', 1) for p in parts[1].split('&')]}
|
||||||
filters = [Filter.from_str(f) for f in (query['filters'].split(',') if 'filters' in query else [])]
|
filters = [Filter.from_str(f) for f in (query['filters'].split(',') if 'filters' in query else [])]
|
||||||
|
try:
|
||||||
offset = int(query['offset']) if 'offset' in query else None
|
offset = int(query['offset']) if 'offset' in query else None
|
||||||
limit = int(query['limit']) if 'limit' in query else None
|
limit = int(query['limit']) if 'limit' in query else None
|
||||||
|
except ValueError:
|
||||||
|
raise BadRequestError('Invalid integer value in query')
|
||||||
order = query['order'] if 'order' in query else None
|
order = query['order'] if 'order' in query else None
|
||||||
|
|
||||||
if path == '/wine/varieties':
|
if path == '/wine/varieties':
|
||||||
|
Reference in New Issue
Block a user