kopia lustrzana https://github.com/jprochazka/adsb-receiver
Added aircraft endpoints.
rodzic
21c143db78
commit
f2ae197d7a
|
|
@ -4,7 +4,7 @@ from flask_apscheduler import APScheduler
|
|||
from flask_jwt_extended import JWTManager
|
||||
from backend.jobs.data_collection import data_collection_job
|
||||
from backend.jobs.maintenance import maintenance_job
|
||||
from backend.routes.flights import flights
|
||||
from backend.routes.aircraft import aircraft
|
||||
from backend.routes.blog import blog
|
||||
from backend.routes.flights import flights
|
||||
from backend.routes.links import links
|
||||
|
|
@ -22,6 +22,7 @@ def create_app():
|
|||
app.config["JWT_REFRESH_TOKEN_EXPIRES"] = timedelta(days=365)
|
||||
jwt = JWTManager(app)
|
||||
|
||||
app.register_blueprint(aircraft)
|
||||
app.register_blueprint(blog)
|
||||
app.register_blueprint(flights)
|
||||
app.register_blueprint(links)
|
||||
|
|
@ -30,6 +31,7 @@ def create_app():
|
|||
app.register_blueprint(tokens)
|
||||
app.register_blueprint(users)
|
||||
|
||||
|
||||
# /API/SCHEDULER
|
||||
|
||||
app.config["SCHEDULER_API_ENABLED"] = True
|
||||
|
|
@ -40,12 +42,14 @@ def create_app():
|
|||
scheduler.init_app(app)
|
||||
scheduler.start()
|
||||
|
||||
|
||||
# /API/DOCS
|
||||
|
||||
@app.route('/api/docs')
|
||||
def get_docs():
|
||||
return render_template('swaggerui.html')
|
||||
|
||||
|
||||
# INIT_APP
|
||||
|
||||
from . import db
|
||||
|
|
|
|||
|
|
@ -0,0 +1,114 @@
|
|||
import logging
|
||||
|
||||
from flask import abort, Blueprint, jsonify, request
|
||||
from flask_jwt_extended import jwt_required
|
||||
from backend.db import create_connection
|
||||
|
||||
aircraft = Blueprint('aircraft', __name__)
|
||||
|
||||
|
||||
@aircraft.route('/api/aircraft/<string:icao>', methods=['GET'])
|
||||
def get_aircraft_by_icao(icao):
|
||||
data=[]
|
||||
|
||||
try:
|
||||
connection = create_connection()
|
||||
cursor=connection.cursor()
|
||||
cursor.execute("SELECT * FROM aircraft WHERE icao = %s", (icao,))
|
||||
columns=[x[0] for x in cursor.description]
|
||||
result=cursor.fetchall()
|
||||
for result in result:
|
||||
data.append(dict(zip(columns,result)))
|
||||
except Exception as ex:
|
||||
logging.error(f"Error encountered while trying to get aircraft using ICAO {icao}", exc_info=ex)
|
||||
abort(500, description="Internal Server Error")
|
||||
finally:
|
||||
connection.close()
|
||||
|
||||
if not data:
|
||||
abort(404, description="Not Found")
|
||||
|
||||
return jsonify(data[0]), 200
|
||||
|
||||
@aircraft.route('/api/aircraft/<icao>/positions', methods=['GET'])
|
||||
def get_aircraft_positions(icao):
|
||||
offset = request.args.get('offset', default=0, type=int)
|
||||
limit = request.args.get('limit', default=500, type=int)
|
||||
if offset < 0 or limit < 1 or limit > 1000:
|
||||
abort(400, description="Bad Request")
|
||||
|
||||
positions=[]
|
||||
|
||||
try:
|
||||
connection = create_connection()
|
||||
cursor=connection.cursor()
|
||||
cursor.execute("SELECT id FROM aircraft WHERE icao = %s", (icao,))
|
||||
aircraft_id = cursor.fetchone()[0]
|
||||
cursor.execute("SELECT * FROM positions WHERE aircraft = %s ORDER BY time LIMIT %s, %s", (aircraft_id, offset, limit))
|
||||
columns=[x[0] for x in cursor.description]
|
||||
result=cursor.fetchall()
|
||||
for result in result:
|
||||
positions.append(dict(zip(columns,result)))
|
||||
except Exception as ex:
|
||||
logging.error(f"Error encountered while trying to get flight positions for aircraft ICAO {icao}", exc_info=ex)
|
||||
abort(500, description="Internal Server Error")
|
||||
finally:
|
||||
connection.close()
|
||||
|
||||
data={}
|
||||
data['offset'] = offset
|
||||
data['limit'] = limit
|
||||
data['count'] = len(positions)
|
||||
data['positions'] = positions
|
||||
|
||||
return jsonify(data), 200
|
||||
|
||||
@aircraft.route('/api/aircraft', methods=['GET'])
|
||||
def get_aircraft():
|
||||
offset = request.args.get('offset', default=0, type=int)
|
||||
limit = request.args.get('limit', default=50, type=int)
|
||||
if offset < 0 or limit < 1 or limit > 100:
|
||||
abort(400, description="Bad Request")
|
||||
|
||||
aircraft_data=[]
|
||||
|
||||
try:
|
||||
connection = create_connection()
|
||||
cursor=connection.cursor()
|
||||
cursor.execute("SELECT * FROM aircraft ORDER BY last_seen DESC, icao LIMIT %s, %s", (offset, limit))
|
||||
columns=[x[0] for x in cursor.description]
|
||||
result=cursor.fetchall()
|
||||
for result in result:
|
||||
aircraft_data.append(dict(zip(columns,result)))
|
||||
except Exception as ex:
|
||||
logging.error('Error encountered while trying to get aircraft', exc_info=ex)
|
||||
abort(500, description="Internal Server Error")
|
||||
finally:
|
||||
connection.close()
|
||||
|
||||
data={}
|
||||
data['offset'] = offset
|
||||
data['limit'] = limit
|
||||
data['count'] = len(aircraft_data)
|
||||
data['aircraft'] = aircraft_data
|
||||
|
||||
response = jsonify(data)
|
||||
response.headers.add('Access-Control-Allow-Origin', '*')
|
||||
return response, 200
|
||||
|
||||
@aircraft.route('/api/aircraft/count', methods=['GET'])
|
||||
def get_aircraft_count():
|
||||
try:
|
||||
connection = create_connection()
|
||||
cursor=connection.cursor()
|
||||
cursor.execute("SELECT COUNT(*) FROM aircraft")
|
||||
count=cursor.fetchone()[0]
|
||||
except Exception as ex:
|
||||
logging.error('Error encountered while trying to get aircraft count', exc_info=ex)
|
||||
abort(500, description="Internal Server Error")
|
||||
finally:
|
||||
connection.close()
|
||||
|
||||
response = jsonify(aircraft=count)
|
||||
response.headers.add('Access-Control-Allow-Origin', '*')
|
||||
return response, 200
|
||||
|
|
@ -8,7 +8,6 @@ flights = Blueprint('flights', __name__)
|
|||
|
||||
|
||||
@flights.route('/api/flight/<string:flight>', methods=['GET'])
|
||||
@jwt_required()
|
||||
def get_flight(flight):
|
||||
data=[]
|
||||
|
||||
|
|
@ -32,7 +31,6 @@ def get_flight(flight):
|
|||
return jsonify(data[0]), 200
|
||||
|
||||
@flights.route('/api/flight/<flight>/positions', methods=['GET'])
|
||||
@jwt_required()
|
||||
def get_flight_positions(flight):
|
||||
offset = request.args.get('offset', default=0, type=int)
|
||||
limit = request.args.get('limit', default=500, type=int)
|
||||
|
|
|
|||
|
|
@ -12,6 +12,11 @@ externalDocs:
|
|||
servers:
|
||||
- url: http://127.0.0.1:5000/api
|
||||
tags:
|
||||
- name: aircraft
|
||||
description: Access and manage aircraft data
|
||||
externalDocs:
|
||||
description: Wiki documentation
|
||||
url: https://github.com/jprochazka/adsb-receiver/wiki
|
||||
- name: blog
|
||||
description: Access and manage blog data
|
||||
externalDocs:
|
||||
|
|
@ -48,6 +53,141 @@ tags:
|
|||
description: Wiki documentation
|
||||
url: https://github.com/jprochazka/adsb-receiver/wiki
|
||||
paths:
|
||||
/aircraft/{icao}:
|
||||
get:
|
||||
tags:
|
||||
- aircraft
|
||||
summary: Get data related to the specified aircraft
|
||||
description: Returns all data related to the aircraft assigned the specified ICAO
|
||||
operationId: getAircraftByIcao
|
||||
parameters:
|
||||
- name: icao
|
||||
in: path
|
||||
description: The ICAO assigned the aircraft in question
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
items:
|
||||
$ref: '#/components/schemas/Aircraft'
|
||||
'401':
|
||||
description: Unauthorized
|
||||
'404':
|
||||
description: Not Found
|
||||
'500':
|
||||
description: Internal Server Error
|
||||
/aircraft/{icao}/positions:
|
||||
get:
|
||||
tags:
|
||||
- aircraft
|
||||
summary: Get postion data for an aircraft
|
||||
description: Returns recorded positions for the specified aircraft assigned the specified ICAO
|
||||
operationId: getAircraftPositions
|
||||
parameters:
|
||||
- name: icao
|
||||
in: path
|
||||
description: The ICAO of the aircraft for which the position data is being requested
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
- name: offset
|
||||
in: query
|
||||
description: The number of positions to be skipped before adding the first item to the result
|
||||
required: false
|
||||
schema:
|
||||
type: integer
|
||||
default: 0
|
||||
minimum: 0
|
||||
- name: limit
|
||||
in: query
|
||||
description: Maximum number of positions to be returned
|
||||
required: false
|
||||
schema:
|
||||
type: integer
|
||||
default: 500
|
||||
minimum: 1
|
||||
maximum: 1000
|
||||
responses:
|
||||
'200':
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
items:
|
||||
$ref: '#/components/schemas/GetAircraftPositionsResponse'
|
||||
'401':
|
||||
description: Unauthorized
|
||||
'400':
|
||||
description: Bad Request
|
||||
'500':
|
||||
description: Internal Server Error
|
||||
/aircraft:
|
||||
get:
|
||||
tags:
|
||||
- aircraft
|
||||
summary: Get data related to multiple aircraft
|
||||
description: Returns data for multiple aircraft ordered by the date they were created
|
||||
operationId: getAircraft
|
||||
parameters:
|
||||
- name: offset
|
||||
in: query
|
||||
description: The number of aircraft to be skipped before adding the first item to the result
|
||||
required: false
|
||||
schema:
|
||||
type: integer
|
||||
default: 0
|
||||
minimum: 0
|
||||
- name: limit
|
||||
in: query
|
||||
description: Maximum number of aircraft to be returned
|
||||
required: false
|
||||
schema:
|
||||
type: integer
|
||||
default: 50
|
||||
minimum: 1
|
||||
maximum: 100
|
||||
responses:
|
||||
'200':
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
items:
|
||||
$ref: '#/components/schemas/GetAircraftResponse'
|
||||
'401':
|
||||
description: Unauthorized
|
||||
'400':
|
||||
description: Bad Request
|
||||
'500':
|
||||
description: Internal Server Error
|
||||
/aircraft/count:
|
||||
get:
|
||||
tags:
|
||||
- aircraft
|
||||
summary: Gets the number of tracked aircraft
|
||||
description: Returns the total number of aircraft currently being tracked
|
||||
operationId: GetAircraftCount
|
||||
responses:
|
||||
'200':
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
items:
|
||||
$ref: '#/components/schemas/GetAircraftCountResponse'
|
||||
'401':
|
||||
description: Unauthorized
|
||||
'500':
|
||||
description: Internal Server Error
|
||||
/blog/post:
|
||||
post:
|
||||
tags:
|
||||
|
|
@ -203,8 +343,6 @@ paths:
|
|||
get:
|
||||
tags:
|
||||
- flights
|
||||
security:
|
||||
- bearerAuth: []
|
||||
summary: Get data related to the specified flight
|
||||
description: Returns all data related to the flight assigned the specified flight
|
||||
operationId: getFlight
|
||||
|
|
@ -234,8 +372,6 @@ paths:
|
|||
get:
|
||||
tags:
|
||||
- flights
|
||||
security:
|
||||
- bearerAuth: []
|
||||
summary: Get postion data for a flight
|
||||
description: Returns recorded positions for the specified flight
|
||||
operationId: getFlightPositions
|
||||
|
|
@ -857,6 +993,50 @@ components:
|
|||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
schemas:
|
||||
Aircraft:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
icao:
|
||||
type: string
|
||||
first_seen:
|
||||
type: string
|
||||
format: date-time
|
||||
last_seen:
|
||||
type: string
|
||||
format: date-time
|
||||
GetAircraftPositionsResponse:
|
||||
type: object
|
||||
properties:
|
||||
offset:
|
||||
type: integer
|
||||
limit:
|
||||
type: integer
|
||||
count:
|
||||
type: integer
|
||||
positions:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Position'
|
||||
GetAircraftResponse:
|
||||
type: object
|
||||
properties:
|
||||
offset:
|
||||
type: integer
|
||||
limit:
|
||||
type: integer
|
||||
count:
|
||||
type: integer
|
||||
flights:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Aircraft'
|
||||
GetAircraftCountResponse:
|
||||
type: object
|
||||
properties:
|
||||
aircraft:
|
||||
type: integer
|
||||
BlogPost:
|
||||
type: object
|
||||
properties:
|
||||
|
|
|
|||
Ładowanie…
Reference in New Issue