def upload_motion_file(): # noqa: E501 """Uploads a csv motion file, only a few checks are performed. # noqa: E501 :param file: :type file: strstr :param trip_uuid: :type trip_uuid: :rtype: ApiResponse """ # if user does not select file, browser also # submit an empty part without filename file = connexion.request.files['file'] trip_uuid = connexion.request.form['tripUUID'] if file.filename == '': return ApiResponse(code=400, message='no file selected'), 400 if file and '.' in file.filename and file.filename.rsplit('.', 1)[1].lower() == 'csv': mongodb_interface.insert_new_file(trip_uuid.replace("\"", ""), file) # enqueueing a trip road_analysis job queue.Job(job_type=const.TRIP_ANALYSIS_JOB, job_data=trip_uuid.replace("\"", "")).enqueue_job( const.TRIP_ANALYSIS_QUEUE, const.RABBITMQ_HOST) return ApiResponse(code=200, message='ok'), 200 return ApiResponse(code=400, message='wrong file selected'), 400
def delete_reservation(reservation, username=None, cluster=None, project=None): # noqa: E501 """delete reservation Delete Reservation # noqa: E501 :param reservation: reservation uuid to delete :type reservation: str :param username: username who request to delete :type username: str :param cluster: either cluster name or cluster_urn :type cluster: str :param project: The project name :type project: str :rtype: ApiResponse """ if username is None: username = emulab.EMULAB_EXPERIMENT_USER if project is None: project = emulab.EMULAB_PROJ emulab_cmd = '{} sudo -u {} manage_reservations delete {} {}'.format( emulab.SSH_BOSS, username, project, reservation) emulab_stdout = emulab.send_request(emulab_cmd) json_string = emulab.parse_response(emulab_stdout) response = ApiResponse(**(json.loads(json_string))) return response
def data_delete(st_case=None): # noqa: E501 """Delete a record from training data # noqa: E501 :param st_case: ST_CASE value of the object(s) to be deleted :type st_case: List[str] :rtype: ApiResponse """ # Create connection to the DB and cursor. if os.environ["DATABASE_URL"]: conn = psycopg2.connect(os.environ["DATABASE_URL"]) else: conn = psycopg2.connect( "host=localhost dbname=accidents_raw user=postgres password=password" ) cur = conn.cursor() statement = "DELETE FROM accident_vehicle_master WHERE ST_CASE = " \ + body.st_case + ";" cur.execute(statement) # Print result from delete command print(cur.statusmessage) conn.commit() response = ApiResponse(code=200, type="Good", message="Successful delete") return response
def vehicle_delete(body): # noqa: E501 """Delete a record of a vehicle # noqa: E501 :param body: Created user object :type body: dict | bytes :rtype: ApiResponse """ if connexion.request.is_json: body = Vehicle.from_dict(connexion.request.get_json()) # noqa: E501 # Create connection to the DB and cursor. if os.environ["DATABASE_URL"]: conn = psycopg2.connect(os.environ["DATABASE_URL"]) else: conn = psycopg2.connect( "host=localhost dbname=accidents_raw user=postgres password=password" ) cur = conn.cursor() statement = "DELETE FROM vehicles WHERE ST_CASE = " + body.st_case cur.execute(statement) # Print result from delete command print(cur.statusmessage) conn.commit() response = ApiResponse(code=200, type="Good", message="Successful delete") return response
def get_car(garage_id, car_id): # noqa: E501 """get car details # noqa: E501 :param garage_id: id of garage :type garage_id: int :param car_id: id of car :type car_id: int :rtype: CarDetail """ stmt = 'select * from car as c where c.id = ? and c.garage_id = ?' args = (car_id, garage_id) record = get_db().execute(stmt, args).fetchone() if record is None: return ApiResponse(code=404, type='error', message='cannot find car {} in garage {}'.format( car_id, garage_id)), 404 dikt = {key: record[key] for key in record.keys()} dikt['garage'] = '{}/garages/{}'.format(api_base_url(), garage_id) return CarDetail.from_dict(dikt)
def delete_profile(name, username=None, project=None): # noqa: E501 """delete profile delete profile # noqa: E501 :param name: name of profile to delete :type name: str :param username: username for the request :type username: str :param project: project name :type project: str :rtype: None """ if username is None: username = emulab.EMULAB_EXPERIMENT_USER if project is None: project = emulab.EMULAB_PROJ emulab_cmd = '{} sudo -u {} manage_profile delete {},{}'.format( emulab.SSH_BOSS, username, project, name) emulab.send_request(emulab_cmd) response = ApiResponse( code=0, output="Please use getProfile to check whether success or fail") return response
def remove_car(garage_id, car_id): # noqa: E501 """remove car from garage # noqa: E501 :param garage_id: id of garage :type garage_id: int :param car_id: id of car :type car_id: int :rtype: None """ with get_db() as con: cur = con.execute( ''' delete from car where id = ? and garage_id = ? ''', (car_id, garage_id)) if cur.rowcount < 1: return ApiResponse( code=404, type='error', message='cannot find car {} in garage {}'.format( car_id, garage_id)), 404
def create_profile(body): # noqa: E501 """create profile Create Profile # noqa: E501 :param body: Profile Object :type body: dict | bytes :rtype: ApiResponse """ if connexion.request.is_json: req = Profile.from_dict(connexion.request.get_json()) # noqa: E501 if req.creator is None: req.creator = emulab.EMULAB_EXPERIMENT_USER if req.project is None: req.project = emulab.EMULAB_PROJ xmlfile = emulab.write_profile_xml(req.project, req.name, req.script, req.repourl) xmlpath = emulab.send_file(xmlfile) emulab_cmd = '{} sudo -u {} manage_profile create {}'.format( emulab.SSH_BOSS, req.creator, xmlpath) emulab.send_request(emulab_cmd) # clean up the temporary files os.unlink(xmlfile) emulab_cmd = '{} sudo rm {}'.format(emulab.SSH_BOSS, xmlpath) emulab.send_request(emulab_cmd) response = ApiResponse( code=0, output="Please use getProfile to check whether success or fail") return response
def TotalDaysExistError(employee_id: str = None, year: int = None, type='total days'): return ApiResponse( code=1014, type=type, message='Total days for employee id\'{}\', year \'{}\' already exists'. format(employee_id, year))
def insert_new_trip(): # noqa: E501 """Insert a new bike trip and start the background processing. # noqa: E501 :param body: :type body: dict | bytes :rtype: ApiResponse """ if not connexion.request.is_json: return ApiResponse(code=400, message="not a valid json"), 400 try: body = Trip.from_dict(connexion.request.get_json()) # noqa: E501 mongodb_interface.insert_new_trip(body.to_dict()) except mongodb_interface.pymongo.errors.DuplicateKeyError: return ApiResponse(code=400, message="trip already exist"), 400 return ApiResponse(code=200, message="ok"), 200
def LeaveDaysPeriodError(start_date: date = None, end_date: date = None, type='leave days'): return ApiResponse( code=1017, type=type, message= 'Leave days start date \'{}\' must be less or equal to end date \'{}\'' .format(start_date, end_date))
def TotalDaysNotFoundError(id: int = None, employee_id: str = None, year: int = None, type='total days'): return ApiResponse( code=1013, type=type, message= 'Total days not found, id: \'{}\', employee_id: \'{}\', year: \'{}\''. format(id, employee_id, year))
def LeaveDaysExistError(employee_id: str = None, start_date: date = None, end_date: date = None, type='leave days'): return ApiResponse( code=1016, type=type, message= 'Leave days for employee id\'{}\', for period (\'{}\', \'{}\') already exists' .format(employee_id, start_date, end_date))
def LeaveDaysNotFoundError(id: int = None, employee_id: str = None, leave_date: date = None, type='leave days'): return ApiResponse( code=1015, type=type, message= 'Leave days not found, id: \'{}\', employee_id: \'{}\', leave date: \'{}\'' .format(id, employee_id, leave_date))
def create_reservation(body, validate=None): # noqa: E501 """create reservation Create Reservation # noqa: E501 :param body: Reservation Object :type body: dict | bytes :param validate: set to true if just to validate instead of actual reserve :type validate: bool :rtype: ApiResponse """ if connexion.request.is_json: reservation = Reservation.from_dict( connexion.request.get_json()) # noqa: E501 logger.info(reservation) check_option = '' if validate: check_option = '-n' if reservation.username is None: reservation.username = emulab.EMULAB_EXPERIMENT_USER if reservation.project is None: reservation.project = emulab.EMULAB_PROJ logger.info('use default project \'{}\''.format(reservation.project)) notefile = tempfile.NamedTemporaryFile(delete=False) notefile.write(reservation.experiment.encode()) notefile.close() subprocess.check_output(['chmod', '644', notefile.name], stderr=subprocess.STDOUT) filepath = emulab.send_file(notefile.name) os.unlink(notefile.name) emulab_cmd = \ '{} sudo -u {} manage_reservations reserve {} -N {} -t {} -p emulab -s {} -e {} {} {}'.format( emulab.SSH_BOSS, reservation.username, check_option, filepath, reservation.type, reservation.start, reservation.end, reservation.project, reservation.nodes) emulab_stdout = emulab.send_request(emulab_cmd) json_string = emulab.parse_response(emulab_stdout) response = ApiResponse(**(json.loads(json_string))) # delete the temporary files emulab_cmd = '{} sudo rm {}'.format(emulab.SSH_BOSS, filepath) emulab.send_request(emulab_cmd) return response
def delete_trip(): # noqa: E501 """Deletes a trip. # noqa: E501 :param trip_uuid: :type trip_uuid: :rtype: ApiResponse """ trip_uuid = connexion.request.args.get('tripUUID', None) mongodb_interface.delete_trip_by_trip_uuid(trip_uuid) return ApiResponse(code=200, message="ok"), 200
def update_car_registration(garage_id, car_id, car_update): # noqa: E501 """update existing car registration # noqa: E501 :param garage_id: id of garage :type garage_id: int :param car_id: id of car :type car_id: int :param body: new car registration :type body: dict | bytes :rtype: None """ upd = CarUpdate.from_dict(car_update) try: with get_db() as con: cur = con.execute( ''' update car set registration = ? where id = ? and garage_id = ? ''', (upd.registration, car_id, garage_id)) if cur.rowcount < 1: return ApiResponse( code=404, type='error', message='cannot find car {} in garage {}'.format( car_id, garage_id)), 404 except sqlite3.IntegrityError as err: msg, = err.args if 'UNIQUE' in msg: return ApiResponse( code=600, type='error', message='registration {} is already taken'.format( upd.registration)), 400
def get_long_device_uuid(): # noqa: E501 """Get the long device UUID from the short device UUID # noqa: E501 :param short_device_uuid: :type short_device_uuid: str :rtype: str """ short_device_uuid = connexion.request.args.get('shortDeviceUUID', None) device_uuid_map = mongodb_interface.get_device_uuid_map_by_short_device_uuid( short_device_uuid) if not device_uuid_map: return ApiResponse(code=404, message='device uuid not found'), 404 return device_uuid_map['device_uuid']
def empty_garage(garage_id): # noqa: E501 """remove all cars from a garage # noqa: E501 :param garage_id: id of garage in which to parc the car :type garage_id: int :rtype: None """ with get_db() as con: cur = con.execute('delete from car where garage_id = ?', (garage_id, )) if cur.rowcount < 1: return ApiResponse( code=404, type='error', message='cannot find garage {}'.format(garage_id)), 404
def get_motion_file(): # noqa: E501 """Gets a csv motion file. # noqa: E501 :param trip_uuid: :type trip_uuid: :rtype: str """ trip_uuid = connexion.request.args.get('tripUUID', None) file = mongodb_interface.get_file_by_filename(trip_uuid) if not file: return ApiResponse(code=400, message='trip not found'), 400 output = make_response(file.read()) output.headers['Content-Disposition'] = 'attachment; filename={}.csv'.format(trip_uuid) output.headers['Content-type'] = 'text/csv' return output
def purge_garage(garage_id): # noqa: E501 """delete an existing garage and all of its cars # noqa: E501 :param garage_id: id of existing garage to be purged :type garage_id: int :rtype: None """ with get_db() as con: # removes associated cars by cascade cur = con.execute('delete from garage where id = ?', (garage_id, )) if cur.rowcount < 1: return ApiResponse( code=404, type='error', message='cannot find garage {}'.format(garage_id)), 404
def create_experiment(body): # noqa: E501 """create a experiment instantiate/start experiment # noqa: E501 :param body: Experiment Object :type body: dict | bytes :rtype: ApiResponse """ if connexion.request.is_json: req = Experiment.from_dict(connexion.request.get_json()) # noqa: E501 urn = req.cluster if 'urn' not in urn: urn = os.getenv('URN_' + req.cluster) elif 'authority+cm' not in urn: urn = urn + '+authority+cm' logger.info('urn = {}'.format(urn)) if ',' not in req.profile: req.profile = emulab.EMULAB_PROJ + ',' + req.profile if req.username is None: req.username = emulab.EMULAB_EXPERIMENT_USER if req.project is None: req.project = emulab.EMULAB_PROJ # update the profile from repo update_repo_cmd = '{} sudo -u {} manage_profile updatefromrepo {}'.format( emulab.SSH_BOSS, req.username, req.profile) emulab.send_request(update_repo_cmd) emulab_cmd = '{} sudo -u {} start-experiment -a {} -w --name {} --project {} {}'.format( emulab.SSH_BOSS, req.username, urn, req.name, req.project, req.profile) emulab_stdout = emulab.send_request(emulab_cmd) return ApiResponse( code=0, output="Please use getExperiment to check whether success or fail")
def get_trip_by_trip_uuid(): # noqa: E501 """Gets a trip given a tripUUID # noqa: E501 :param trip_uuid: :type trip_uuid: :rtype: Trip """ trip_uuid = connexion.request.args.get('tripUUID', None) trip = mongodb_interface.get_trip_by_trip_uuid(trip_uuid) if not trip: return ApiResponse(code=400, message='trip not found'), 400 raw_points = mongodb_interface.get_points_by_points_id(trip.get('bumpy_points', [])) trip['bumpy_points'] = [] for raw_point in raw_points: trip['bumpy_points'].append({ 'lat': raw_point['loc']['coordinates'][1], 'lon': raw_point['loc']['coordinates'][0], 'bumpy_score': raw_point['bumpy_score'] }) return FullProcessedTrip().from_dict(trip), 200
def get_cars(garage_id, min_price=0, max_price=SQL_INF): # noqa: E501 """get all cars of a garage # noqa: E501 :param garage_id: id of garage in which to parc the car :type garage_id: int :param min_price: minimum inclusive price :type min_price: str :param max_price: maximum inclusive price :type max_price: str :rtype: List[Car] """ try: decimal.Decimal(min_price) decimal.Decimal(max_price) except decimal.InvalidOperation: return ApiResponse( code=605, type='error', message='invalid input, min_ and max_price must be decimal') stmt = ''' select id, registration, brand, model, price from car as c where c.garage_id = ? and c.price >= ? and c.price <= ? ''' args = (garage_id, min_price, max_price) records = get_db().execute(stmt, args).fetchall() return [ Car.from_dict({key: record[key] for key in record.keys()}) for record in records ]
def get_garage(garage_id): # noqa: E501 """get the details of an existing garage # noqa: E501 :param garage_id: id of existing garage :type garage_id: int :rtype: GarageDetail """ stmt = ''' select g.id, name, address, date_created, max_capacity, group_concat(c.id) as cars from garage as g left join car as c on g.id = c.garage_id where g.id = ? group by g.id ''' args = (garage_id, ) record = get_db().execute(stmt, args).fetchone() if record is None: return ApiResponse( code=404, type='error', message='cannot find garage {}'.format(garage_id)), 404 dikt = {key: record[key] for key in record.keys()} car_ids = [] if dikt['cars'] is None else dikt['cars'].split(',') dikt['cars'] = [ '{}/garages/{}/cars/{}'.format(api_base_url(), garage_id, car_id) for car_id in car_ids ] return GarageDetail.from_dict(dikt)
def EmployeeEmailExistError(email: str, type='employee'): return ApiResponse( code=1009, type=type, message='Employee with email \'{}\' already exists'.format(email))
def add_car(garage_id, car): # noqa: E501 """add a car to a garage # noqa: E501 :param garage_id: id of garage in which to parc the car :type garage_id: int :param body: car to create :type body: dict | bytes :rtype: CarDetail """ carDetail = CarDetail.from_dict(car) # added input validation - this should go into the model code # but the framework does not catch and wrap errors other than # can be expected from the yaml specification try: decimal.Decimal(carDetail.price) except decimal.InvalidOperation: return ApiResponse(code=604, type='error', message='invalid input, price must be decimal'), 400 try: with get_db() as con: cursor = con.cursor() # TODO: verify isolation level # this calls for a transaction: # - insert the car (optimistically) # - then check garage capacity to eventually rollback cursor.execute('BEGIN TRANSACTION') check_stmt = ''' select g.max_capacity, count(c.id) as no_cars from garage as g left join car as c on g.id = c.garage_id where g.id = ? group by g.id ''' check_args = (garage_id, ) check_record = cursor.execute(check_stmt, check_args).fetchone() # garage not found if check_record is None: return ApiResponse( code=602, type='error', message='cannot find garage {}'.format(garage_id)), 400 from pprint import pprint pprint({key: check_record[key] for key in check_record.keys()}) # garage already full if check_record['no_cars'] > check_record['max_capacity']: return ApiResponse( code=603, type='error', message='garage {} is already full'.format(garage_id)), 400 create_stmt = ''' insert into car (registration, brand, model, price, garage_id) values (?, ?, ?, ? ,?); ''' create_args = (carDetail.registration, carDetail.brand, carDetail.model, carDetail.price, garage_id) cursor.execute(create_stmt, create_args) cursor.execute('END TRANSACTION') carDetail.id = cursor.lastrowid return carDetail, 201, { 'Location': '{}/garages/{}/cars/{}'.format(api_base_url(), garage_id, carDetail.id) } except sqlite3.IntegrityError as err: msg, = err.args if 'UNIQUE' in msg: return ApiResponse(code=601, type='error', message='car registration already exists'), 400 elif 'FOREIGN KEY' in msg: return ApiResponse( code=602, type='error', message='cannot find garage {}'.format(garage_id)), 400
def EmployeeNotFoundError(id: int = None, email: str = None, type='employee'): return ApiResponse( code=1010, type=type, message='Employee not found, id: \'{}\', email: \'{}\''.format( id, email))
def TeamExistError(name: str, type='team'): return ApiResponse( code=1011, type=type, message='Team with name \'{}\' already exists'.format(name))
def TeamNotFoundError(id: int = None, name: str = None, type='team'): return ApiResponse( code=1012, type=type, message='Team not found, id: \'{}\', name: \'{}\''.format(id, name))