Rebase into previous commit
This commit is contained in:
parent
1adfe6519f
commit
5f6b7339c4
13
bootstrap.py
13
bootstrap.py
|
@ -19,9 +19,6 @@ from hub_api.greenery_catalog import GreeneryCatalogEntry, GreeneryCatalogEntrie
|
||||||
from hub_api.session import SessionStart, SessionEnd, KeepSessionAlive
|
from hub_api.session import SessionStart, SessionEnd, KeepSessionAlive
|
||||||
from hub_api.uptime import Uptime
|
from hub_api.uptime import Uptime
|
||||||
from hub_api.usage_catalog import UsageCatalogEntry, UsageCatalogEntries, UsageCatalogNames
|
from hub_api.usage_catalog import UsageCatalogEntry, UsageCatalogEntries, UsageCatalogNames
|
||||||
from hub_api.user import User, UserLogin
|
|
||||||
from hub_api.city_info import CityInfo, City
|
|
||||||
from hub_api.city_commands import Update, Delete, Search, List, Save
|
|
||||||
|
|
||||||
sh.begin_time = datetime.datetime.now()
|
sh.begin_time = datetime.datetime.now()
|
||||||
app = flask.Flask('cerc_api')
|
app = flask.Flask('cerc_api')
|
||||||
|
@ -42,19 +39,9 @@ api.add_resource(UsageCatalogEntries, '/v1.4/usage-catalog/entries')
|
||||||
api.add_resource(UsageCatalogNames, '/v1.4/usage-catalog/names')
|
api.add_resource(UsageCatalogNames, '/v1.4/usage-catalog/names')
|
||||||
|
|
||||||
# Session
|
# Session
|
||||||
api.add_resource(User, '/v1.4/user')
|
|
||||||
api.add_resource(UserLogin, '/v1.4/user/login')
|
|
||||||
api.add_resource(SessionStart, '/v1.4/session/start')
|
api.add_resource(SessionStart, '/v1.4/session/start')
|
||||||
api.add_resource(SessionEnd, '/v1.4/session/end')
|
api.add_resource(SessionEnd, '/v1.4/session/end')
|
||||||
api.add_resource(KeepSessionAlive, '/v1.4/session/keep_alive')
|
api.add_resource(KeepSessionAlive, '/v1.4/session/keep_alive')
|
||||||
api.add_resource(CityInfo, '/v1.4/city_info')
|
|
||||||
api.add_resource(City, '/v1.4/city')
|
|
||||||
api.add_resource(Save, '/v1.4/city/save_city')
|
|
||||||
api.add_resource(Update, '/v1.4/city/update_city')
|
|
||||||
api.add_resource(Delete, '/v1.4/city/delete_city')
|
|
||||||
api.add_resource(List, '/v1.4/city/list_cities')
|
|
||||||
api.add_resource(Search, '/v1.4/city/search_city')
|
|
||||||
|
|
||||||
|
|
||||||
with open("hub_api/docs/openapi-specs.yml", "r") as stream:
|
with open("hub_api/docs/openapi-specs.yml", "r") as stream:
|
||||||
swagger_config = {
|
swagger_config = {
|
||||||
|
|
|
@ -15,147 +15,71 @@ from pathlib import Path
|
||||||
import os
|
import os
|
||||||
from hub_api.config import Config
|
from hub_api.config import Config
|
||||||
|
|
||||||
headers = {'Content-Type': 'application/json'}
|
|
||||||
|
|
||||||
|
|
||||||
class CityInfo(Resource, Config):
|
class CityInfo(Resource, Config):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
|
@role_required([UserRoles.Admin.value])
|
||||||
def get(self, city_id):
|
def get(self, city_id):
|
||||||
"""
|
|
||||||
API call to search database for city by city_id
|
|
||||||
:return: json, status code, headers
|
|
||||||
"""
|
|
||||||
city = self.get_city(city_id)
|
city = self.get_city(city_id)
|
||||||
if city is not None:
|
|
||||||
return Response(response=json.dumps({
|
|
||||||
'id': city.id, 'name': city.name, 'srs_name': city.srs_name,
|
|
||||||
'time_zone': city.time_zone, 'version': city.city_version, 'country': city.country_code,
|
|
||||||
'lat': city.latitude, 'lon': city.longitude, 'lower_corner': city.lower_corner,
|
|
||||||
'upper_corner': city.upper_corner, 'created': city.created, 'updated': city.updated,
|
|
||||||
'user': {'id': city.user.id, 'name': city.user.name, 'email': city.user.email,
|
|
||||||
'role': city.user.role.value}
|
|
||||||
}, default=str), status=200, headers=headers)
|
|
||||||
return Response(response=json.dumps({'err_msg': 'City not found'}), status=404, headers=headers)
|
|
||||||
|
|
||||||
@role_required([UserRoles.Admin.value])
|
# TODO: this is only for dompark project and need to be removed in future versions.
|
||||||
def put(self, city_id):
|
floor_area = 0
|
||||||
"""
|
wall_construction = 'unknown'
|
||||||
API call to update city in database with new city_file by city_id
|
floor_construction = 'unknown'
|
||||||
:return: json, status code, headers
|
roof_construction = 'unknown'
|
||||||
"""
|
window_type = 'unknown'
|
||||||
allowed_ext = {'gml', '3dm', 'xml', 'obj', 'rhino'}
|
building_dic = {}
|
||||||
try:
|
for building in city.buildings:
|
||||||
city_file = request.files['city_file']
|
|
||||||
ext = city_file.filename.rsplit('.', 1)[1].lower()
|
|
||||||
|
|
||||||
if ext in allowed_ext:
|
usages = [] # This is only valid for dompark project as all the building have the same usage
|
||||||
city_file_type = ext
|
if building.lower_corner[2] == 0:
|
||||||
if ext == 'gml':
|
floor_area += building.floor_area
|
||||||
city_file_type = 'citygml'
|
for internal_zone in building.internal_zones:
|
||||||
elif ext == '3dm':
|
for usage_zone in internal_zone.usage_zones:
|
||||||
city_file_type = 'rhino'
|
usages.append({'percentage': usage_zone.percentage, 'usage': usage_zone.usage})
|
||||||
|
for thermal_zone in internal_zone.thermal_zones:
|
||||||
file_path = (
|
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||||
Path(__file__).parent.parent / 'data/uploaded_city/{}'.format(city_file.filename)).resolve()
|
if thermal_boundary.parent_surface.type == 'Ground':
|
||||||
city_file.save(file_path)
|
floor_construction = thermal_boundary.construction_name
|
||||||
city = GeometryFactory(city_file_type, file_path).city
|
elif thermal_boundary.parent_surface.type == 'Wall':
|
||||||
|
wall_construction = thermal_boundary.construction_name
|
||||||
saved_city = self.import_db_factory.update_city(city_id, city)
|
for thermal_opening in thermal_boundary.thermal_openings:
|
||||||
if os.path.exists(file_path):
|
if thermal_opening.construction_name is not None:
|
||||||
os.remove(file_path)
|
window_type = thermal_opening.construction_name
|
||||||
if saved_city is None:
|
break
|
||||||
saved_city = self.export_db_factory.get_city(city_id)
|
|
||||||
return Response(headers=headers, response=json.dumps({
|
|
||||||
'id': saved_city.id, 'name': saved_city.name, 'srs_name': saved_city.srs_name,
|
|
||||||
'time_zone': saved_city.time_zone, 'version': saved_city.city_version,
|
|
||||||
'country': saved_city.country_code,
|
|
||||||
'lat': saved_city.latitude, 'lon': saved_city.longitude,
|
|
||||||
'lower_corner': saved_city.lower_corner,
|
|
||||||
'upper_corner': saved_city.upper_corner, 'created': saved_city.created,
|
|
||||||
'updated': saved_city.updated,
|
|
||||||
'user': {'id': saved_city.user.id, 'name': saved_city.user.name, 'email': saved_city.user.email,
|
|
||||||
'role': saved_city.user.role.value}
|
|
||||||
}, default=str), status=201)
|
|
||||||
return Response(response=json.dumps(saved_city), status=200)
|
|
||||||
else:
|
else:
|
||||||
return Response(response=json.dumps({'err_msg': 'Unknown city file type'}), status=400)
|
roof_construction = thermal_boundary.construction_name
|
||||||
|
name = building.human_readable_name
|
||||||
except Exception as err:
|
year_of_construction = str(building.year_of_construction)
|
||||||
logger.error(err)
|
building_dic = {
|
||||||
return Response(response=json.dumps({'err_msg': 'Sorry an error occurred while updating city'}), status=400)
|
'name': str(name),
|
||||||
|
'floor_area': str(floor_area),
|
||||||
@role_required([UserRoles.Admin.value])
|
'year_of_construction': str(year_of_construction),
|
||||||
def delete(self, city_id):
|
'usages': usages,
|
||||||
"""
|
'wall_construction': wall_construction,
|
||||||
API call to delete city from database by city_id
|
'floor_construction': floor_construction,
|
||||||
:return: json, status code, headers
|
'roof_construction': roof_construction,
|
||||||
"""
|
'window_type': window_type,
|
||||||
try:
|
'default_archetype': 'industry ASHRAE_2004:4A non_standard_dompark'
|
||||||
return Response(headers=headers, response=json.dumps(
|
}
|
||||||
self.import_db_factory.delete_city(city_id=city_id)), status=201)
|
|
||||||
except Exception as err:
|
|
||||||
logger.error(err)
|
|
||||||
return Response(response=json.dumps({'err_msg': 'Sorry an error occurred while deleting city'}), status=400)
|
|
||||||
|
|
||||||
class CitySearch(Resource, Config):
|
|
||||||
"""
|
|
||||||
CitySearch class for searching for cities via an API call
|
|
||||||
"""
|
|
||||||
def __init__(self):
|
|
||||||
super().__init__()
|
|
||||||
|
|
||||||
def get(self, search_term, query):
|
|
||||||
"""
|
|
||||||
API call to search city depending on search_term and specified query
|
|
||||||
:return: json, status code, headers
|
|
||||||
"""
|
|
||||||
if search_term == "city_name":
|
|
||||||
city = self.get_city_by_name(query)
|
|
||||||
|
|
||||||
if city is not None:
|
|
||||||
return Response(response=json.dumps({
|
|
||||||
'id': city.id, 'name': city.name, 'srs_name': city.srs_name,
|
|
||||||
'time_zone': city.time_zone, 'version': city.city_version, 'country': city.country_code,
|
|
||||||
'lat': city.latitude, 'lon': city.longitude, 'lower_corner': city.lower_corner,
|
|
||||||
'upper_corner': city.upper_corner, 'created': city.created, 'updated': city.updated,
|
|
||||||
'user': {'id': city.user.id, 'name': city.user.name, 'email': city.user.email,
|
|
||||||
'role': city.user.role.value}
|
|
||||||
}, default=str), status=200, headers=headers)
|
|
||||||
return Response(response=json.dumps({'err_msg': 'City not found'}), status=404, headers=headers)
|
|
||||||
|
|
||||||
elif search_term == "user_id":
|
|
||||||
cities = self.get_city_by_user(query)
|
|
||||||
|
|
||||||
if cities is not None:
|
|
||||||
for city in cities:
|
|
||||||
#TODO - iterate through cities packaging them into a list and return the packaged JSON
|
|
||||||
return Response(response=json.dumps({
|
|
||||||
'id': city.id, 'name': city.name, 'srs_name': city.srs_name,
|
|
||||||
'time_zone': city.time_zone, 'version': city.city_version, 'country': city.country_code,
|
|
||||||
'lat': city.latitude, 'lon': city.longitude, 'lower_corner': city.lower_corner,
|
|
||||||
'upper_corner': city.upper_corner, 'created': city.created, 'updated': city.updated,
|
|
||||||
'user': {'id': city.user.id, 'name': city.user.name, 'email': city.user.email,
|
|
||||||
'role': city.user.role.value}
|
|
||||||
}, default=str), status=200, headers=headers)
|
|
||||||
return Response(response=json.dumps({'err_msg': 'No cities found by user'}), status=404, headers=headers)
|
|
||||||
|
|
||||||
elif search_term == "list_all":
|
|
||||||
#TODO - implement API call to query all define cities in the database
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
buildings = [building_dic]
|
||||||
|
response = {'city_name': city.name,
|
||||||
|
'climate_reference_city': str(city.climate_reference_city),
|
||||||
|
'buildings': buildings
|
||||||
|
}
|
||||||
|
return Response(json.dumps(response), status=200)
|
||||||
|
|
||||||
|
|
||||||
class City(Resource, Config):
|
class City(Resource, Config):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
@role_required([UserRoles.Admin.value])
|
@role_required([UserRoles.Admin.value])
|
||||||
def post(self):
|
def post(self):
|
||||||
"""
|
|
||||||
API call to create city in database with newcity_file by city_id
|
|
||||||
:return: json, status code, headers
|
|
||||||
"""
|
|
||||||
allowed_ext = {'gml', '3dm', 'xml', 'obj', 'rhino'}
|
allowed_ext = {'gml', '3dm', 'xml', 'obj', 'rhino'}
|
||||||
try:
|
try:
|
||||||
city_file = request.files['city_file']
|
city_file = request.files['city_file']
|
||||||
|
@ -184,10 +108,9 @@ class City(Resource, Config):
|
||||||
'user': {'id': saved_city.user.id, 'name': saved_city.user.name, 'email': saved_city.user.email,
|
'user': {'id': saved_city.user.id, 'name': saved_city.user.name, 'email': saved_city.user.email,
|
||||||
'role': saved_city.user.role.value}
|
'role': saved_city.user.role.value}
|
||||||
}, default=str), status=201)
|
}, default=str), status=201)
|
||||||
return Response(response=json.dumps(saved_city), status=200, headers=headers)
|
return Response(response=json.dumps(saved_city), status=200)
|
||||||
else:
|
else:
|
||||||
return Response(response=json.dumps({'err_msg': 'Unknown city file type'}), status=400, headers=headers)
|
return Response(response=json.dumps({'err_msg': 'Unknown city file type'}), status=400)
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
logger.error(err)
|
logger.error(err)
|
||||||
return Response(response=json.dumps({'err_msg': 'Sorry an error occurred while creating city'}),
|
return Response(response=json.dumps({'err_msg': 'Sorry an error occurred while creating city'}), status=400)
|
||||||
status=400, headers=headers)
|
|
||||||
|
|
|
@ -3,41 +3,28 @@ Config
|
||||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||||
Copyright © 2023 Project Peter Yefi peteryefi@gmail.com
|
Copyright © 2023 Project Peter Yefi peteryefi@gmail.com
|
||||||
"""
|
"""
|
||||||
import os
|
|
||||||
from hub.exports.db_factory import DBFactory as CityExportFactory
|
from hub.exports.db_factory import DBFactory as CityExportFactory
|
||||||
from hub.imports.db_factory import DBFactory
|
from hub.imports.db_factory import DBFactory
|
||||||
from hub.imports.user_factory import UserFactory
|
import os
|
||||||
from hub.exports.user_factory import UserFactory as ExUserFactory
|
import pickle
|
||||||
|
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
db_name = None
|
self.export_db_factory = CityExportFactory(db_name='hub_prod', app_env='PROD',
|
||||||
app_env = None
|
|
||||||
if os.getenv("FLASK_DEBUG") == 'production':
|
|
||||||
db_name = 'hub_prod'
|
|
||||||
app_env = 'PROD'
|
|
||||||
elif os.getenv("FLASK_DEBUG") == 'testing':
|
|
||||||
db_name = 'hub_test'
|
|
||||||
app_env = 'TEST'
|
|
||||||
|
|
||||||
self.export_db_factory = CityExportFactory(db_name=db_name, app_env=app_env,
|
|
||||||
dotenv_path="{}/.env".format(os.path.expanduser('~')))
|
dotenv_path="{}/.env".format(os.path.expanduser('~')))
|
||||||
self.import_db_factory = DBFactory(db_name=db_name, app_env=app_env,
|
self.import_db_factory = DBFactory(db_name='hub_prod', app_env='PROD',
|
||||||
dotenv_path="{}/.env".format(os.path.expanduser('~')))
|
|
||||||
self.user_factory = UserFactory(db_name=db_name, app_env=app_env,
|
|
||||||
dotenv_path="{}/.env".format(os.path.expanduser('~')))
|
|
||||||
self.ex_user_factory = ExUserFactory(db_name=db_name, app_env=app_env,
|
|
||||||
dotenv_path="{}/.env".format(os.path.expanduser('~')))
|
dotenv_path="{}/.env".format(os.path.expanduser('~')))
|
||||||
|
|
||||||
def get_city(self, city_id):
|
def get_city(self, city_id):
|
||||||
return self.export_db_factory.get_city(city_id)
|
city_obj = self.export_db_factory.get_city(city_id)
|
||||||
|
city = pickle.loads(city_obj.city)
|
||||||
def get_city_by_name(self, city_name):
|
for building in city.buildings:
|
||||||
return self.export_db_factory.get_city_by_name(city_name)
|
building.heated = True
|
||||||
|
building.cooled = True
|
||||||
def get_city_by_user(self, user_id):
|
building.attic_heated = 0
|
||||||
return self.export_db_factory.get_city_by_user(user_id)
|
building.basement_heated = 0
|
||||||
|
for surface in building.surfaces:
|
||||||
|
surface.swr = 0.2
|
||||||
|
return city
|
||||||
|
|
|
@ -3,7 +3,7 @@ info:
|
||||||
description: NextGen Cities Institute API
|
description: NextGen Cities Institute API
|
||||||
termsOfService: http://swagger.io/terms/
|
termsOfService: http://swagger.io/terms/
|
||||||
contact:
|
contact:
|
||||||
email: nextgen-cities@gmail.com
|
email: peteryefi@gmail.com
|
||||||
version: 1.4
|
version: 1.4
|
||||||
externalDocs:
|
externalDocs:
|
||||||
description: Find out more about Swagger
|
description: Find out more about Swagger
|
||||||
|
@ -11,18 +11,13 @@ externalDocs:
|
||||||
paths:
|
paths:
|
||||||
/v1.4/uptime:
|
/v1.4/uptime:
|
||||||
get:
|
get:
|
||||||
|
parameters:
|
||||||
|
[]
|
||||||
tags:
|
tags:
|
||||||
- Uptime
|
- Uptime
|
||||||
summary: API uptime
|
summary: API uptime
|
||||||
operationId: uptime
|
operationId: uptime
|
||||||
description: Retrieve current API uptime
|
description: Retrieve current API uptime
|
||||||
parameters:
|
|
||||||
- in: header
|
|
||||||
name: appId
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
required: true
|
|
||||||
description: the Id of the application access this API
|
|
||||||
responses:
|
responses:
|
||||||
'200':
|
'200':
|
||||||
description: Request sucessful
|
description: Request sucessful
|
||||||
|
@ -30,410 +25,6 @@ paths:
|
||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/components/schemas/Uptime'
|
$ref: '#/components/schemas/Uptime'
|
||||||
|
|
||||||
/v1.4/city:
|
|
||||||
post:
|
|
||||||
tags:
|
|
||||||
- city
|
|
||||||
summary: Create a city
|
|
||||||
operationId: createCity
|
|
||||||
description: Create a new city with a file upload
|
|
||||||
parameters:
|
|
||||||
- in: header
|
|
||||||
name: appId
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
required: true
|
|
||||||
description: the Id of the application access this API
|
|
||||||
requestBody:
|
|
||||||
content:
|
|
||||||
multipart/form-data:
|
|
||||||
schema:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
city_file:
|
|
||||||
type: string
|
|
||||||
format: binary
|
|
||||||
required: true
|
|
||||||
responses:
|
|
||||||
'201':
|
|
||||||
description: City created successfully
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/City'
|
|
||||||
'200':
|
|
||||||
description: City not created
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/ApiResponse'
|
|
||||||
'400':
|
|
||||||
description: Bad Request
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/ApiResponse'
|
|
||||||
'404':
|
|
||||||
description: City not found
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/ApiResponse'
|
|
||||||
'403':
|
|
||||||
description: Forbidden
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/ApiResponse'
|
|
||||||
'401':
|
|
||||||
description: Unauthorized
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/ApiResponse'
|
|
||||||
'500':
|
|
||||||
description: Internal server error
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/ApiResponse'
|
|
||||||
security:
|
|
||||||
- BearerAuth: []
|
|
||||||
/v1.4/city/{city_id}:
|
|
||||||
get:
|
|
||||||
tags:
|
|
||||||
- city
|
|
||||||
summary: Get a city
|
|
||||||
operationId: getCity
|
|
||||||
description: Retrieve a city with a given city ID
|
|
||||||
parameters:
|
|
||||||
- in: header
|
|
||||||
name: appId
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
required: true
|
|
||||||
description: the ID of the application access this API
|
|
||||||
- in: path
|
|
||||||
name: city_id
|
|
||||||
schema:
|
|
||||||
type: integer
|
|
||||||
required: true
|
|
||||||
description: Numeric ID of the city to get
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: City retrieved successfully
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/City'
|
|
||||||
'400':
|
|
||||||
description: Bad Request
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/ApiResponse'
|
|
||||||
'404':
|
|
||||||
description: City not found
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/ApiResponse'
|
|
||||||
'403':
|
|
||||||
description: Forbidden
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/ApiResponse'
|
|
||||||
'401':
|
|
||||||
description: Unauthorized
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/ApiResponse'
|
|
||||||
'500':
|
|
||||||
description: Internal server error
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/ApiResponse'
|
|
||||||
put:
|
|
||||||
tags:
|
|
||||||
- city
|
|
||||||
summary: Update a city
|
|
||||||
operationId: updateCity
|
|
||||||
description: Create a new city with a file upload
|
|
||||||
parameters:
|
|
||||||
- in: header
|
|
||||||
name: appId
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
required: true
|
|
||||||
description: the Id of the application access this API
|
|
||||||
- in: path
|
|
||||||
name: city_id
|
|
||||||
schema:
|
|
||||||
type: integer
|
|
||||||
required: true
|
|
||||||
description: Numeric ID of the city to update
|
|
||||||
requestBody:
|
|
||||||
content:
|
|
||||||
multipart/form-data:
|
|
||||||
schema:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
city_file:
|
|
||||||
type: string
|
|
||||||
format: binary
|
|
||||||
required: true
|
|
||||||
responses:
|
|
||||||
'201':
|
|
||||||
description: City updated successfully
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/City'
|
|
||||||
'200':
|
|
||||||
description: City not updated
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/ApiResponse'
|
|
||||||
'400':
|
|
||||||
description: Bad Request
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/ApiResponse'
|
|
||||||
'404':
|
|
||||||
description: City not found
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/ApiResponse'
|
|
||||||
'403':
|
|
||||||
description: Forbidden
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/ApiResponse'
|
|
||||||
'401':
|
|
||||||
description: Unauthorized
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/ApiResponse'
|
|
||||||
'500':
|
|
||||||
description: Internal server error
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/ApiResponse'
|
|
||||||
security:
|
|
||||||
- BearerAuth: [ ]
|
|
||||||
delete:
|
|
||||||
tags:
|
|
||||||
- city
|
|
||||||
summary: Delete a city
|
|
||||||
operationId: deleteCity
|
|
||||||
description: Delete city with specified city_id
|
|
||||||
parameters:
|
|
||||||
- in: header
|
|
||||||
name: appId
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
required: true
|
|
||||||
description: the ID of the application access this API
|
|
||||||
- in: path
|
|
||||||
name: city_id
|
|
||||||
schema:
|
|
||||||
type: integer
|
|
||||||
required: true
|
|
||||||
description: Numeric ID of the city to delete
|
|
||||||
responses:
|
|
||||||
'201':
|
|
||||||
description: City deleted successfully
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/City'
|
|
||||||
'200':
|
|
||||||
description: City not deleted
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/ApiResponse'
|
|
||||||
'400':
|
|
||||||
description: Bad Request
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/ApiResponse'
|
|
||||||
'404':
|
|
||||||
description: City not found
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/ApiResponse'
|
|
||||||
'403':
|
|
||||||
description: Forbidden
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/ApiResponse'
|
|
||||||
'401':
|
|
||||||
description: Unauthorized
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/ApiResponse'
|
|
||||||
'500':
|
|
||||||
description: Internal server error
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/ApiResponse'
|
|
||||||
security:
|
|
||||||
- BearerAuth: [ ]
|
|
||||||
/v1.4/user:
|
|
||||||
post:
|
|
||||||
tags:
|
|
||||||
- user
|
|
||||||
summary: Create user
|
|
||||||
description: This can only be done by the logged in admin.
|
|
||||||
operationId: createUser
|
|
||||||
parameters:
|
|
||||||
- in: header
|
|
||||||
name: appId
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
required: true
|
|
||||||
description: the Id of the application access this API
|
|
||||||
requestBody:
|
|
||||||
description: Created user object
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/User'
|
|
||||||
application/xml:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/User'
|
|
||||||
responses:
|
|
||||||
'201':
|
|
||||||
description: User created successfully
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/User'
|
|
||||||
'400':
|
|
||||||
description: Bad Request
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/ApiResponse'
|
|
||||||
'403':
|
|
||||||
description: Forbidden
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/ApiResponse'
|
|
||||||
'401':
|
|
||||||
description: Unauthorized
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/ApiResponse'
|
|
||||||
'500':
|
|
||||||
description: Internal server error
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/ApiResponse'
|
|
||||||
security:
|
|
||||||
- BearerAuth: [ ]
|
|
||||||
put:
|
|
||||||
tags:
|
|
||||||
- user
|
|
||||||
summary: Update user
|
|
||||||
description: This can only be done by the logged in admin.
|
|
||||||
operationId: updateUser
|
|
||||||
requestBody:
|
|
||||||
description: Update user object
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/User'
|
|
||||||
application/xml:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/User'
|
|
||||||
responses:
|
|
||||||
'201':
|
|
||||||
description: User updated successfully
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/User'
|
|
||||||
'400':
|
|
||||||
description: Bad Request
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/ApiResponse'
|
|
||||||
'403':
|
|
||||||
description: Forbidden
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/ApiResponse'
|
|
||||||
'401':
|
|
||||||
description: Unauthorized
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/ApiResponse'
|
|
||||||
'500':
|
|
||||||
description: Internal server error
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/ApiResponse'
|
|
||||||
security:
|
|
||||||
- BearerAuth: [ ]
|
|
||||||
/v1.4/user/login:
|
|
||||||
post:
|
|
||||||
tags:
|
|
||||||
- user
|
|
||||||
summary: Logs user into the system
|
|
||||||
description: ''
|
|
||||||
operationId: loginUser
|
|
||||||
parameters:
|
|
||||||
- in: header
|
|
||||||
name: appId
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
required: true
|
|
||||||
description: the Id of the application access this API
|
|
||||||
requestBody:
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/Login'
|
|
||||||
required: true
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Login successful
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/LoginRes'
|
|
||||||
'400':
|
|
||||||
description: Invalid username/password supplied
|
|
||||||
'500':
|
|
||||||
description: Internal server error
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/ApiResponse'
|
|
||||||
components:
|
components:
|
||||||
schemas:
|
schemas:
|
||||||
Uptime:
|
Uptime:
|
||||||
|
@ -443,135 +34,3 @@ components:
|
||||||
type: string
|
type: string
|
||||||
format: hh:mm:ss.ms
|
format: hh:mm:ss.ms
|
||||||
example: "00:09:53.600281"
|
example: "00:09:53.600281"
|
||||||
City:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
id:
|
|
||||||
type: integer
|
|
||||||
format: int64
|
|
||||||
example: 10
|
|
||||||
name:
|
|
||||||
type: string
|
|
||||||
example: Montreal
|
|
||||||
srs_name:
|
|
||||||
type: string
|
|
||||||
example: EPSG:26918
|
|
||||||
country:
|
|
||||||
type: string
|
|
||||||
example: ca
|
|
||||||
lon:
|
|
||||||
type: float
|
|
||||||
example: 0.38292983
|
|
||||||
lat:
|
|
||||||
type: float
|
|
||||||
example: 0.92898883
|
|
||||||
time_zone:
|
|
||||||
type: string
|
|
||||||
example: utc
|
|
||||||
city_version:
|
|
||||||
type: integer
|
|
||||||
format: int64
|
|
||||||
example: 1
|
|
||||||
lower_corner:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: float
|
|
||||||
example: [610610.7547462888,5035770.347264212,566.5784301757819]
|
|
||||||
upper_corner:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: float
|
|
||||||
example: [610610.7547462888,5035770.347264212,566.5784301757819]
|
|
||||||
user:
|
|
||||||
type: object
|
|
||||||
$ref: '#/components/schemas/User'
|
|
||||||
created:
|
|
||||||
type: string
|
|
||||||
example: 2023-01-15 18:40:54.64877
|
|
||||||
updated:
|
|
||||||
type: string
|
|
||||||
example: 2023-01-15 18:40:54.64877
|
|
||||||
User:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
id:
|
|
||||||
type: integer
|
|
||||||
format: int64
|
|
||||||
example: 10
|
|
||||||
name:
|
|
||||||
type: string
|
|
||||||
example: Peter Yefi
|
|
||||||
email:
|
|
||||||
type: string
|
|
||||||
format: email
|
|
||||||
example: peteryefi@gmail.com
|
|
||||||
password:
|
|
||||||
type: string
|
|
||||||
example: 'Hub@183838'
|
|
||||||
role:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- Admin
|
|
||||||
- Hub_Reader
|
|
||||||
required:
|
|
||||||
- name
|
|
||||||
- email
|
|
||||||
- password
|
|
||||||
- role
|
|
||||||
Login:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
email:
|
|
||||||
type: string
|
|
||||||
example: peteryefi@gmail.com
|
|
||||||
password:
|
|
||||||
type: string
|
|
||||||
example: 'Hub@183838'
|
|
||||||
required:
|
|
||||||
- email
|
|
||||||
- password
|
|
||||||
LoginRes:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
token:
|
|
||||||
type: string
|
|
||||||
example: eylskdkdjfkdj67uhbnmkhbn908uyhndh
|
|
||||||
user:
|
|
||||||
type: object
|
|
||||||
$ref: '#/components/schemas/User'
|
|
||||||
ApiResponse:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
code:
|
|
||||||
type: integer
|
|
||||||
format: int32
|
|
||||||
message:
|
|
||||||
type: string
|
|
||||||
Uptime:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
uptime:
|
|
||||||
type: string
|
|
||||||
requestBodies:
|
|
||||||
User:
|
|
||||||
description: User object that is to be created
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/User'
|
|
||||||
application/xml:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/User'
|
|
||||||
CityArray:
|
|
||||||
description: List of city object
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
$ref: '#/components/schemas/City'
|
|
||||||
securitySchemes:
|
|
||||||
BearerAuth:
|
|
||||||
type: http
|
|
||||||
scheme: bearer
|
|
||||||
bearerFormat: JWT
|
|
|
@ -12,8 +12,6 @@ from flask_restful import Resource
|
||||||
|
|
||||||
import hub_api.helpers.session_helper as sh
|
import hub_api.helpers.session_helper as sh
|
||||||
|
|
||||||
headers = {'Content-Type': 'application/json'}
|
|
||||||
|
|
||||||
class Uptime(Resource):
|
class Uptime(Resource):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
pass
|
||||||
|
@ -21,4 +19,4 @@ class Uptime(Resource):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get():
|
def get():
|
||||||
uptime = {"uptime": f"{datetime.datetime.now() - sh.begin_time}"}
|
uptime = {"uptime": f"{datetime.datetime.now() - sh.begin_time}"}
|
||||||
return Response(response=json.dumps(uptime), headers=headers)
|
return Response(json.dumps(uptime))
|
||||||
|
|
|
@ -25,4 +25,3 @@ jwt==1.3.1
|
||||||
flagger==3.1.0
|
flagger==3.1.0
|
||||||
flasgger
|
flasgger
|
||||||
cerc-hub
|
cerc-hub
|
||||||
psycopg2
|
|
Loading…
Reference in New Issue
Block a user