Merge remote-tracking branch 'origin/main' into server_instance

This commit is contained in:
Guille Gutierrez 2023-04-12 15:27:21 -04:00
commit ddb43aab23
7 changed files with 26576 additions and 29 deletions

View File

@ -18,7 +18,7 @@ import hub_api.helpers.session_helper as sh
from hub_api.control.session import SessionStart, SessionEnd, KeepSessionAlive
from hub_api.control.uptime import Uptime
from hub_api.buildings.meb import Meb
from hub_api.geolocation.reverse import Reverse
sh.begin_time = datetime.datetime.now()
app = flask.Flask('cerc_api')
@ -35,6 +35,9 @@ api.add_resource(KeepSessionAlive, '/v1.4/session/keep_alive')
# Buildings
api.add_resource(Meb, '/v1.4/buildings/meb')
# GeoLocation
api.add_resource(Reverse, '/v1.4/geolocation/reverse/<latitude>/<longitude>', endpoint='reverse')
with open("hub_api/docs/openapi-specs.yml", "r") as stream:
swagger_config = {
"headers": [],

View File

@ -1,9 +1,11 @@
import json
from flask import Response, request
from flask_restful import Resource
from hub_api.helpers.session_helper import active_session, session
from hub_api.config import Config
from hub_api.helpers.session_helper import session, refresh_session
class Meb(Resource, Config):
def __init__(self):
@ -16,21 +18,23 @@ class Meb(Resource, Config):
session_id = request.headers.get('session_id', None)
token = request.headers.get('token', None)
application_uuid = request.headers.get('application_uuid', None)
if active_session(session_id, token, application_uuid):
application_id = session(session_id)['application_id']
user_id = session(session_id)['user_id']
payload = request.get_json()
results = self.export_db_factory.results(user_id, application_id, payload)
if results == {}:
# no data found for the given parameters
return Response(json.dumps({'result': 'succeed', 'results': results}), status=200)
# deserialize the response to return pure json
city_name = next(iter(results))
for building_results in results[city_name]:
values = []
for value in building_results['insel meb']:
key = next(iter(value))
values.append({key: json.loads(value[key])})
building_results['insel meb'] = values
return Response(json.dumps({'result': 'succeed', 'results': results}), status=200)
return Response(json.dumps({'error': 'unauthorized'}), status=403)
_session = refresh_session(session_id, token, application_uuid)
if _session is None:
return Response(json.dumps({'error': 'unauthorized'}), status=403)
application_id = session(session_id)['application_id']
user_id = session(session_id)['user_id']
token = {'token': _session['token']}
payload = request.get_json()
results = self.export_db_factory.results(user_id, application_id, payload)
if results == {}:
# no data found for the given parameters
return Response(json.dumps({'result': 'succeed', 'results': results}), status=200, headers=token)
# deserialize the response to return pure json
city_name = next(iter(results))
for building_results in results[city_name]:
values = []
for value in building_results['insel meb']:
key = next(iter(value))
values.append({key: json.loads(value[key])})
building_results['insel meb'] = values
return Response(json.dumps({'result': 'succeed', 'results': results}), status=200, headers=token)

View File

@ -76,11 +76,11 @@ class KeepSessionAlive(Resource):
session_id = request.headers.get('session_id', None)
token = request.headers.get('token', None)
application_uuid = request.headers.get('application_uuid', None)
session = refresh_session(session_id, token, application_uuid)
_session = refresh_session(session_id, token, application_uuid)
if session is None:
if _session is None:
return Response(json.dumps({'error': 'unauthorized'}), status=403)
response = Response(json.dumps({'result': 'succeed'}), status=200)
response.headers['token'] = session['token']
response.headers['token'] = _session['token']
return response

26456
hub_api/data/cities15000.txt Normal file

File diff suppressed because it is too large Load Diff

View File

@ -38,6 +38,7 @@ paths:
name: password
schema:
type: string
format: password
required: true
description: the password for the user accessing this API
- in: header
@ -180,6 +181,43 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/unauthorized'
/v1.4/geolocation/reverse/{latitude}/{longitude}:
get:
parameters:
- in: path
name: latitude
schema:
type: string
required: true
- in: path
name: longitude
schema:
type: string
required: true
tags:
- Reverse geolocation information
summary: Retrieve the geolocation information from the given latitude and longitude
operationId: reverse
description: Retrieve the geolocation information from the given latitude and longitude and renew the token
responses:
'200':
description: Succeed
content:
application/json:
schema:
$ref: '#/components/schemas/reverse'
headers:
token:
type: string
format: uuid
description: Token expected in next operation header
example: '77e1c83b-7bb0-437b-bc50-a7a58e5660ac'
'403':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/unauthorized'
components:
securitySchemes:
session-id:
@ -202,6 +240,18 @@ components:
type: string
format: hh:mm:ss.ms
example: '00:09:53.600281'
reverse:
type: object
properties:
country:
type: string
example: 'CA'
city:
type: string
example: 'Montreal'
climate_zone:
type: string
example: '6'
unauthorized:
type: object
properties:

View File

@ -0,0 +1,35 @@
import json
import math
from pathlib import Path
from flask import Response
from flask.views import MethodView
from hub_api.config import Config
class Reverse(MethodView, Config):
def __init__(self):
super().__init__()
self._reverse_path = Path(Path(__file__).parent.parent / 'data/cities15000.txt').resolve()
def get(self, latitude: float, longitude: float):
latitude = float(latitude)
longitude = float(longitude)
distance = math.inf
country = 'unknown'
city = 'unknown'
with open(self._reverse_path, 'r') as f:
for line_number, line in enumerate(f):
fields = line.split('\t')
file_city_name = fields[1]
file_latitude = float(fields[4])
file_longitude = float(fields[5])
file_country_code = fields[8]
new_distance = math.sqrt(pow((latitude-file_latitude),2) + pow((longitude-file_longitude),2))
if distance > new_distance:
distance = new_distance
country = file_country_code
city = file_city_name
return Response(json.dumps({'country': country, 'city':city}), status=200)

View File

@ -22,7 +22,7 @@ def expired_sessions_collector(session_timeout_duration):
"""
while True:
if bool(sessions):
for session in list(sessions):
for _session in list(sessions):
_expire = datetime.datetime.strptime(sessions[session]['expire'], '%Y-%m-%d %H:%M:%S.%f')
if _expire < datetime.datetime.now():
print("session with session_id: ", session, "expired.")
@ -35,10 +35,10 @@ def _validate_session(session_id, token, application_uuid):
Checks if session is valid
"""
try:
session = sessions[session_id]
_session = session(session_id)
if debug_mode:
token = session['token']
return bool(session) and (session['token'] == token) and session['application_uuid'] == application_uuid
token = _session['token']
return bool(_session) and (_session['token'] == token) and _session['application_uuid'] == application_uuid
except KeyError:
return False
@ -61,8 +61,7 @@ def refresh_session(session_id, token, application_uuid):
if _validate_session(session_id, token, application_uuid):
sessions[session_id]['expire'] = str(datetime.datetime.now() + datetime.timedelta(minutes=5))
sessions[session_id]['token'] = str(uuid.uuid4())
return sessions[session_id]
return session(session_id)
return None