Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions homeworks/homework_06_web/data.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"2": {
"departure_time": "11:00",
"arrival_time": "12:00",
"travel_time": "01:00",
"destination_airport": "Sheremetievo",
"type_aircraft": "TU"
},
"3": {
"departure_time": "06:00",
"arrival_time": "08:00",
"travel_time": "02:00",
"destination_airport": "Sheremetievo",
"type_aircraft": "TU"
},
"4": {
"departure_time": "10:00",
"arrival_time": "11:00",
"travel_time": "01:00",
"destination_airport": "Vnukovo",
"type_aircraft": "TU"
}
}
105 changes: 105 additions & 0 deletions homeworks/homework_06_web/data_processing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import json
import sys
from os import path
from marshmallow import Schema, fields, ValidationError


class Cnt:
def __init__(self):
self.cnt = 0
if path.isfile("data.json"):
with open("data.json", 'r', encoding='utf-8')as file:
data = json.loads(file.read())
if len(data) > 0:
self.cnt = max(data.keys())

def new_id(self):
self.cnt += 1
return str(self.cnt)


c = Cnt()


class Flight(Schema):
departure_time = fields.Time(required=True)
arrival_time = fields.Time(required=True)
travel_time = fields.Time(required=True)
destination_airport = fields.Str(required=True)
type_aircraft = fields.Str(required=True)


def is_valid(entry):
schema = Flight()
try:
schema.load(entry)
return True
except ValidationError:
return False


def select_all(sort_by, filter_field, filter_value):
with open("data.json", 'r', encoding='utf-8')as file:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Перекрываешь встроенный метод file и странно, что в пепе нет пробела перед as, так себе выглядит :)

res = json.loads(file.read())
if len(res) == 0:
res = []
else:
res = [{"id_flight": i, "flight": res[i]} for i in res]
if filter_field is not None and filter_value is not None and len(res) > 0:
try:
res = [i for i in res if i["flight"][filter_field] == filter_value]
except BaseException:
return None
if sort_by is not None and len(res) > 0:
try:
res.sort(key=lambda a: a["flight"][sort_by])
except BaseException:
return None
return res


def select(id_flight):
with open("data.json", 'r', encoding='utf-8')as file:
data = json.loads(file.read())
try:
return True, data[str(id_flight)]
except BaseException:
return False, ""


def insert(entry):
with open("data.json", 'r', encoding='utf-8')as file:
data = json.loads(file.read())
if is_valid(entry):
key = c.new_id()
data[key] = entry
with open("data.json", 'w', encoding='utf-8')as file:
json.dump(data, file, ensure_ascii=False, indent=4)
return key
return None


def update(id_flight, flight):
with open("data.json", 'r', encoding='utf-8')as file:
data = json.loads(file.read())
if is_valid(flight):
try:
data[str(id_flight)] = flight
with open("data.json", 'w', encoding='utf-8')as file:
json.dump(data, file, ensure_ascii=False, indent=4)
return True, ""
except BaseException:
pass
return False, '''id_flight not exist or flight format not valid'''


def delete(id_flight):
with open("data.json", 'r', encoding='utf-8')as file:
data = json.loads(file.read())
try:
del data[str(id_flight)]
with open("data.json", 'w', encoding='utf-8')as file:
json.dump(data, file, ensure_ascii=False, indent=4)
Comment on lines +97 to +102
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Почитай https://ru.wikipedia.org/wiki/Don%E2%80%99t_repeat_yourself и подумай, как бы круто код выглядел, вынеси ты общение с бд (файлом) в отдельный класс.

return True, ""
except BaseException:
return False, "id_flight not exist"
31 changes: 31 additions & 0 deletions homeworks/homework_06_web/flight_service.logging
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
2019-11-02 19:40:13,980 - werkzeug - INFO - * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
2019-11-02 19:40:15,725 - flask.app - INFO - {'url': 'http://localhost:5000/show_flights', 'args': {}, 'body': None, 'req_method': 'GET', 'duration': 0.0004, 'response': <Response 29 bytes [200 OK]>, 'http_status': 200}
2019-11-02 19:40:15,725 - werkzeug - INFO - 127.0.0.1 - - [02/Nov/2019 19:40:15] "GET /show_flights HTTP/1.1" 200 -
2019-11-02 19:40:15,734 - flask.app - INFO - {'url': 'http://localhost:5000/new_flight', 'args': {}, 'body': {'departure_time': '10:00', 'arrival_time': '13:00', 'travel_time': '03:00', 'destination_airport': 'Vnukovo', 'type_aircraft': 'TU'}, 'req_method': 'POST', 'duration': 0.0016, 'response': <Response 33 bytes [200 OK]>, 'http_status': 200}
2019-11-02 19:40:15,735 - werkzeug - INFO - 127.0.0.1 - - [02/Nov/2019 19:40:15] "POST /new_flight HTTP/1.1" 200 -
2019-11-02 19:40:15,742 - flask.app - INFO - {'url': 'http://localhost:5000/new_flight', 'args': {}, 'body': {'departure_time': '11:00', 'arrival_time': '12:00', 'travel_time': '01:00', 'destination_airport': 'Sheremetievo', 'type_aircraft': 'TU'}, 'req_method': 'POST', 'duration': 0.0009, 'response': <Response 33 bytes [200 OK]>, 'http_status': 200}
2019-11-02 19:40:15,742 - werkzeug - INFO - 127.0.0.1 - - [02/Nov/2019 19:40:15] "POST /new_flight HTTP/1.1" 200 -
2019-11-02 19:40:15,749 - flask.app - INFO - {'url': 'http://localhost:5000/new_flight', 'args': {}, 'body': {'departure_time': '12:00', 'arrival_time': '25:00', 'travel_time': '02:00', 'destination_airport': 'Vnukovo', 'type_aircraft': 'TU'}, 'req_method': 'POST', 'duration': 0.0015, 'response': <Response 18 bytes [400 BAD REQUEST]>, 'http_status': 400}
2019-11-02 19:40:15,750 - werkzeug - INFO - 127.0.0.1 - - [02/Nov/2019 19:40:15] "POST /new_flight HTTP/1.1" 400 -
2019-11-02 19:40:15,762 - flask.app - INFO - {'url': 'http://localhost:5000/show_flights', 'args': {}, 'body': None, 'req_method': 'GET', 'duration': 0.0006, 'response': <Response 337 bytes [200 OK]>, 'http_status': 200}
2019-11-02 19:40:15,765 - werkzeug - INFO - 127.0.0.1 - - [02/Nov/2019 19:40:15] "GET /show_flights HTTP/1.1" 200 -
2019-11-02 19:40:15,774 - flask.app - INFO - {'url': 'http://localhost:5000/show_flight/1', 'args': {}, 'body': None, 'req_method': 'GET', 'duration': 0.0004, 'response': <Response 151 bytes [200 OK]>, 'http_status': 200}
2019-11-02 19:40:15,774 - werkzeug - INFO - 127.0.0.1 - - [02/Nov/2019 19:40:15] "GET /show_flight/1 HTTP/1.1" 200 -
2019-11-02 19:40:15,780 - flask.app - INFO - {'url': 'http://localhost:5000/show_flight/33', 'args': {}, 'body': None, 'req_method': 'GET', 'duration': 0.0018, 'response': <Response 18 bytes [400 BAD REQUEST]>, 'http_status': 400}
2019-11-02 19:40:15,781 - werkzeug - INFO - 127.0.0.1 - - [02/Nov/2019 19:40:15] "GET /show_flight/33 HTTP/1.1" 400 -
2019-11-02 19:40:15,790 - flask.app - INFO - {'url': 'http://localhost:5000/update_flight', 'args': {}, 'body': {'id_flight': '1', 'flight': {'departure_time': '16:00', 'arrival_time': '17:00', 'travel_time': '01:00', 'destination_airport': 'Vnukovo', 'type_aircraft': 'TU'}}, 'req_method': 'PUT', 'duration': 0.0011, 'response': <Response 17 bytes [200 OK]>, 'http_status': 200}
2019-11-02 19:40:15,790 - werkzeug - INFO - 127.0.0.1 - - [02/Nov/2019 19:40:15] "PUT /update_flight HTTP/1.1" 200 -
2019-11-02 19:40:15,797 - flask.app - INFO - {'url': 'http://localhost:5000/update_flight', 'args': {}, 'body': {'id_flight': '3', 'flight': {'departure_time': 1600, 'arrival_time': '17:00', 'travel_time': '01:00', 'destination_airport': 'Vnukovo', 'type_aircraft': 'TU'}}, 'req_method': 'PUT', 'duration': 0.003, 'response': <Response 77 bytes [400 BAD REQUEST]>, 'http_status': 400}
2019-11-02 19:40:15,797 - werkzeug - INFO - 127.0.0.1 - - [02/Nov/2019 19:40:15] "PUT /update_flight HTTP/1.1" 400 -
Comment on lines +18 to +19
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Все еще скудное журналирование. Как я по этому логу пойму из-за чего, четырехсотка? Этот лог увидит только админ, админ должен понимать что творит сервис без чтения кода. Нормальная тема, когда сервис гигабайты логов в день генерируют, именно для этого есть такое, как "ротация логов". Да, и фича с уровнем логгирования. Когда без изменения кода можно включить дополнительный уровень логов. Пока не зачет :)

2019-11-02 19:40:15,807 - flask.app - INFO - {'url': 'http://localhost:5000/delete_flight', 'args': {}, 'body': {'id_flight': '1'}, 'req_method': 'DELETE', 'duration': 0.001, 'response': <Response 17 bytes [200 OK]>, 'http_status': 200}
2019-11-02 19:40:15,808 - werkzeug - INFO - 127.0.0.1 - - [02/Nov/2019 19:40:15] "DELETE /delete_flight HTTP/1.1" 200 -
2019-11-02 19:40:15,821 - flask.app - INFO - {'url': 'http://localhost:5000/delete_flight', 'args': {}, 'body': {'id_flight': '4'}, 'req_method': 'DELETE', 'duration': 0.0027, 'response': <Response 50 bytes [400 BAD REQUEST]>, 'http_status': 400}
2019-11-02 19:40:15,822 - werkzeug - INFO - 127.0.0.1 - - [02/Nov/2019 19:40:15] "DELETE /delete_flight HTTP/1.1" 400 -
2019-11-02 19:40:15,827 - flask.app - INFO - {'url': 'http://localhost:5000/show_flights', 'args': {}, 'body': None, 'req_method': 'GET', 'duration': 0.0006, 'response': <Response 185 bytes [200 OK]>, 'http_status': 200}
2019-11-02 19:40:15,830 - werkzeug - INFO - 127.0.0.1 - - [02/Nov/2019 19:40:15] "GET /show_flights HTTP/1.1" 200 -
2019-11-02 19:40:15,842 - flask.app - INFO - {'url': 'http://localhost:5000/new_flight', 'args': {}, 'body': {'departure_time': '06:00', 'arrival_time': '08:00', 'travel_time': '02:00', 'destination_airport': 'Sheremetievo', 'type_aircraft': 'TU'}, 'req_method': 'POST', 'duration': 0.0013, 'response': <Response 33 bytes [200 OK]>, 'http_status': 200}
2019-11-02 19:40:15,842 - werkzeug - INFO - 127.0.0.1 - - [02/Nov/2019 19:40:15] "POST /new_flight HTTP/1.1" 200 -
2019-11-02 19:40:15,853 - flask.app - INFO - {'url': 'http://localhost:5000/new_flight', 'args': {}, 'body': {'departure_time': '10:00', 'arrival_time': '11:00', 'travel_time': '01:00', 'destination_airport': 'Vnukovo', 'type_aircraft': 'TU'}, 'req_method': 'POST', 'duration': 0.0023, 'response': <Response 33 bytes [200 OK]>, 'http_status': 200}
2019-11-02 19:40:15,855 - werkzeug - INFO - 127.0.0.1 - - [02/Nov/2019 19:40:15] "POST /new_flight HTTP/1.1" 200 -
2019-11-02 19:40:15,862 - flask.app - INFO - {'url': 'http://localhost:5000/show_flights?sort_by=arrival_time&filter_field=destination_airport&filter_value=Sheremetievo', 'args': {'sort_by': 'arrival_time', 'filter_field': 'destination_airport', 'filter_value': 'Sheremetievo'}, 'body': None, 'req_method': 'GET', 'duration': 0.0017, 'response': <Response 342 bytes [200 OK]>, 'http_status': 200}
2019-11-02 19:40:15,863 - werkzeug - INFO - 127.0.0.1 - - [02/Nov/2019 19:40:15] "GET /show_flights?sort_by=arrival_time&filter_field=destination_airport&filter_value=Sheremetievo HTTP/1.1" 200 -
106 changes: 106 additions & 0 deletions homeworks/homework_06_web/manage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
from flask import Flask, jsonify, request, g
import data_processing as dp
from os import path
import json
import logging
import time

app = Flask(__name__)


@app.route("/show_flights", methods=["GET"])
def show_flights():
sort_by = request.args.get("sort_by")
filter_field = request.args.get("filter_field", default=None)
filter_value = request.args.get("filter_value", default=None)
resp = jsonify(
success=True,
result=dp.select_all(
sort_by,
filter_field,
filter_value))
return resp


@app.route("/show_flight/<int:id_flight>", methods=["GET"])
def show_flight(id_flight):
exist, flight = dp.select(id_flight)
if exist:
resp = jsonify(success=True, flight=flight)
resp.status_code = 200
else:
resp = jsonify(success=False)
resp.status_code = 400
return resp


@app.route("/new_flight", methods=["POST"])
def new_flight():
res = dp.insert(request.json)
if res is not None:
resp = jsonify(success=True, id_flight=res)
resp.status_code = 200
else:
resp = jsonify(success=False)
resp.status_code = 400
return resp


@app.route("/update_flight", methods=["PUT"])
def update_flight():
body = request.json
if "id_flight" not in body or "flight" not in body:
return False, '''"id_flight" of "flight not scecified in request'''
result, message = dp.update(body["id_flight"], body["flight"])
if result:
resp = jsonify(success=True)
resp.status_code = 200
else:
resp = jsonify(success=False, message=message)
resp.status_code = 400
return resp


@app.route("/delete_flight", methods=["DELETE"])
def delete_flights():
body = request.json
if "id_flight" not in body:
return False, '''"id_flight" not scecified in request'''
res, message = dp.delete(body["id_flight"])
if res:
resp = jsonify(success=True)
resp.status_code = 200
else:
resp = jsonify(success=False, message=message)
resp.status_code = 400
return resp


def start_server():
if not path.isfile("data.json"):
with open("data.json", "w", encoding='utf-8') as file:
json.dump(dict(), file, ensure_ascii=False, indent=4)

logging.basicConfig(
filename="flight_service.logging",
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')

@app.before_request
def timer_on():
g.start_handlefunc = time.time()

@app.after_request
def log_request(resp):
dur = round(time.time() - g.start_handlefunc, 4)
app.logger.info({
"url": request.url,
"args": dict(request.args),
"body": request.json,
"req_method": request.method,
"duration": dur,
"response": resp,
"http_status": resp.status_code
})
return resp
app.run()
Loading