Skip to content
This repository has been archived by the owner on Mar 22, 2023. It is now read-only.

Commit

Permalink
error handle updated
Browse files Browse the repository at this point in the history
api_key will be passed to config.py
  • Loading branch information
trakiastudent committed Aug 16, 2021
1 parent 4c87ecc commit 21db007
Show file tree
Hide file tree
Showing 14 changed files with 228 additions and 53 deletions.
6 changes: 6 additions & 0 deletions .idea/other.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 1 addition & 11 deletions __init__.py
Original file line number Diff line number Diff line change
@@ -1,11 +1 @@
from flask import Blueprint, render_template,Flask

from __init__ import *
from dir_home.home_page import home_page

app=Flask(__name__)
app.register_blueprint(blueprint=home_page)

if __name__=="__main__":
app.run(debug=True)

from flask import Blueprint, render_template,Flask
12 changes: 12 additions & 0 deletions app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from __init__ import *

from app import *
from dir_home.home_page import home_page

app=Flask(__name__)
app.register_blueprint(blueprint=home_page)

if __name__=="__main__":
app.run(debug=True)


2 changes: 2 additions & 0 deletions config.py
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
# contains the application configuration parameters.
#add your api_key
yandex_api_key:str= "yandex_geolocator_api_key" # get a free api key --> https://developer.tech.yandex.ru/
3 changes: 2 additions & 1 deletion dir_api/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from requests import get,models,exceptions
from json import loads
from werkzeug.exceptions import BadRequest,Forbidden
from flask import render_template
from flask import render_template,abort
from config import yandex_api_key
23 changes: 14 additions & 9 deletions dir_api/yandex_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ def search_by_address(self,address:str) -> str:
:return: request_result <str> :information for given address
"""


# HTTP error handling [200, 400, 403, 500, 503] First 3 items as informed in official document can be raised by API
# but also 500 and 503 is common mistakes by user internet connection and server status therefore I have added.
try:
Expand All @@ -28,28 +27,29 @@ def search_by_address(self,address:str) -> str:
# The request has succeeded.
if (request_response.status_code==200): # HTTP 200 --> SUCCESSFUL
request_result:str=request_response.text
# return format json structure : str
return request_result

# The server could not understand the request due to invalid syntax. The client SHOULD NOT repeat the request without modifications.
except BadRequest as error: # HTTP 400 --> Bad Request
error_msg: str = "Error: {}".format(error)
return error_msg
abort(400)

# The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource.
# Unlike 401, the client's identity is known to the server.
except Forbidden as error: # HTTP 403 --> Forbidden (wrong API Key)
error_msg: str = "Error: {}".format(error)
return error_msg
abort(403)

# The server has encountered a situation it doesn't know how to handle.
except exceptions.ConnectionError as error: # Internal Server Error 500
error_msg:str="Error: {}".format(error)
return error_msg
abort(500)

# Any other error which is not so common
except exceptions.RequestException as error:
error_msg:str="Error: {}".format(error)
return error_msg
abort(406)

def get_geolocation(self,address:str) -> tuple:
"""
Expand All @@ -60,20 +60,25 @@ def get_geolocation(self,address:str) -> tuple:

# loads function used to parse a valid JSON string and convert it into python dictionary
address_dict:dict=loads(address)

# filter result (dict type) to receive geolocation information
address_dict=address_dict["response"]["GeoObjectCollection"]["featureMember"][0]["GeoObject"]["Point"]["pos"]

# convert result to tuple
address_geolocation:tuple=tuple(address_dict.split(" "))

# result in opposite order <longitude, latitude) therefore we convert this to correct order <latitude, longitude>
# also api return keep information as string therefore we return it to float type --> (float(latitude), float(langitude))
address_geolocation=(float(address_geolocation[1]),float(address_geolocation[0]))

# we received for given address geolocation from http_response and return
# return format (latitude:float,longitude:float) : tuple
return address_geolocation

# here can be used while you test your code.
# if you call this class from another file this part will not be executed
if (__name__=="__main__"):
yandex_obj : YandexGeolocationApi = YandexGeolocationApi("35253147-4db2-4d3a-8a22-b8be047d103f")
result_str : str = yandex_obj.search_by_address("Ankara")
#a=yandex_obj.get_geolocation(result_str)
#print(type(result_str),result_str)
yandex_obj : YandexGeolocationApi = YandexGeolocationApi(yandex_api_key)
result_str : str = yandex_obj.search_by_address("Moscow")
yandex_obj.get_geolocation(result_str)
print(yandex_obj.get_geolocation(result_str))
10 changes: 7 additions & 3 deletions dir_distance/distance.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,16 @@ def find_distance_haversine(self, origin:tuple, destination:tuple) -> float:
#latitude,longitude distance between two addresses
distance_lat :float = radians(lat_destination - lat_origin)
distance_lon :float= radians(lon_destination - lon_origin)
#to be done
# Haversine formula
a = sin(distance_lat / 2) ** 2 + cos(radians(lat_origin)) \
* cos(radians(lat_destination)) * sin(distance_lon / 2) ** 2
#to be done
c = 2 * atan2(sqrt(a), sqrt(1 - a))

#distance between origin and destination as kilometers
distance = RADIUS * c # Great Circle Arc Length(distance)

# via Haversine formula found distance between 2 locations and returned as KM
# return format distanca as KM : float
return distance

def find_nearest_point_mkad(self,origin_address: tuple) -> list:
Expand All @@ -45,8 +47,10 @@ def find_nearest_point_mkad(self,origin_address: tuple) -> list:

# created Distance object to access find_distance_haversine method
distance_obj : Distance = Distance()

# created null list to keep result inside
nearest_destination: list = []

# each_km of Moscow Ring Road
mkad_km: list = [
[1, 37.842762, 55.774558],
Expand Down Expand Up @@ -172,7 +176,7 @@ def find_nearest_point_mkad(self,origin_address: tuple) -> list:
nearest_destination.append(each_km)

# nearest_destination -> [origin_latitude, origin_langitude, nearest_latitude, nearest_longitude, distance_between_origin_nearest ]
nearest_destination=[origin_address[0],origin_address[1],nearest_destination[0][1],nearest_destination[0][2],distance_km]
nearest_destination=[origin_address[0],origin_address[1],nearest_destination[0][2],nearest_destination[0][1],distance_km]
return nearest_destination # list

# here can be used while you test your code.
Expand Down
6 changes: 5 additions & 1 deletion dir_home/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
from flask import Blueprint, render_template,request,abort
from jinja2 import TemplateNotFound
import requests,logging
import requests,logging
from os import abort
from dir_api.yandex_api import YandexGeolocationApi
from dir_distance.distance import Distance
from config import yandex_api_key
44 changes: 29 additions & 15 deletions dir_home/home_page.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from dir_home.__init__ import *
from dir_api.yandex_api import YandexGeolocationApi
from dir_distance.distance import Distance


home_page = Blueprint('dir_home', __name__, template_folder='templates', static_folder='static')

@home_page.route('/',methods=["GET","POST"])
Expand All @@ -9,25 +9,39 @@ def home_page_function() -> str:
home_home_page_function regarding to HTTP request will return html file or log shortest distance
:return: <str> logging or html
"""

#this try except block handle with HtmlNotFoundError
try:
if request.method=="GET":
return render_template("home_page.html")

elif request.method=="POST":
#get address from home_page.html when POST reqeust executed
given_address:str=request.form["address"]
#create YandexGeolocationApi object with API KEY
api_object=YandexGeolocationApi("35253147-4db2-4d3a-8a22-b8be047d103f")
#get geolocation of given address with get_geolocation method
geolocation: tuple=api_object.get_geolocation(api_object.search_by_address(given_address))
distance_object=Distance()
result_list:list=distance_object.find_nearest_point_mkad(geolocation)
#logging to a file
logging.basicConfig(filename="output.log", filemode="w", encoding="utf-8",level=logging.INFO)
result="Origin-->"+str(result_list[0:2])+" Destination-->"+str(result_list[2:4])+" Distance(KM)-->"+str(result_list[4:])
logging.info(str(result))
return render_template("home_page.html")
given_address:str=str(request.form["address"])
try:
if not given_address:
raise ValueError("Empty String")
return render_template("home_page.html")
#create YandexGeolocationApi object with API KEY
api_object=YandexGeolocationApi(yandex_api_key)

#get geolocation of given address with get_geolocation method
geolocation: tuple=api_object.get_geolocation(api_object.search_by_address(given_address))

# creation of Distance object
distance_object=Distance()
result_list:list=distance_object.find_nearest_point_mkad(geolocation)
#logging to a file
logging.basicConfig(filename="output.log", filemode="a", encoding="utf-8",level=logging.INFO)
result="Origin-->"+str(result_list[0:2])+" Destination-->"+str(result_list[2:4])+" Distance(KM)-->"+str(result_list[4:])
logging.info(str(result))

return render_template("home_page.html")

# if not user enter nothing this code will be executed
except ValueError as error:
abort(400)

# if home_page.html is not find in given address this code will be executed
# if html file is not find in given address this code will be executed
except TemplateNotFound:
abort(404)
3 changes: 0 additions & 3 deletions models.py

This file was deleted.

28 changes: 18 additions & 10 deletions output.log
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
INFO:root:Origin-->[41.011218, 28.978178] Destination-->[37.516108, 55.594728] Distance(KM)-->[1737.6415340974795]
INFO:werkzeug:127.0.0.1 - - [15/Aug/2021 23:42:44] "POST / HTTP/1.1" 200 -
INFO:root:Origin-->[39.749891, 37.015746] Destination-->[37.668911, 55.571999] Distance(KM)-->[1760.4952586044587]
INFO:werkzeug:127.0.0.1 - - [15/Aug/2021 23:42:49] "POST / HTTP/1.1" 200 -
INFO:root:Origin-->[39.920763, 32.854049] Destination-->[37.60107, 55.575816] Distance(KM)-->[1776.0379648356338]
INFO:werkzeug:127.0.0.1 - - [15/Aug/2021 23:42:52] "POST / HTTP/1.1" 200 -
INFO:root:Origin-->[48.856663, 2.351556] Destination-->[37.369188, 55.75435] Distance(KM)-->[2471.472711018819]
INFO:werkzeug:127.0.0.1 - - [15/Aug/2021 23:42:55] "POST / HTTP/1.1" 200 -
INFO:root:Origin-->[55.75322, 37.622513] Destination-->[37.841828, 55.747399] Distance(KM)-->[13.743984988551215]
INFO:werkzeug:127.0.0.1 - - [15/Aug/2021 23:43:09] "POST / HTTP/1.1" 200 -
INFO:root:Origin-->[39.920763, 32.854049] Destination-->[55.575816, 37.60107] Distance(KM)-->[1776.0379648356338]
INFO:werkzeug:127.0.0.1 - - [16/Aug/2021 16:15:34] "POST / HTTP/1.1" 200 -
INFO:root:Origin-->[39.749891, 37.015746] Destination-->[55.571999, 37.668911] Distance(KM)-->[1760.4952586044587]
INFO:werkzeug:127.0.0.1 - - [16/Aug/2021 16:15:38] "POST / HTTP/1.1" 200 -
INFO:root:Origin-->[39.920763, 32.854049] Destination-->[55.575816, 37.60107] Distance(KM)-->[1776.0379648356338]
INFO:werkzeug:127.0.0.1 - - [16/Aug/2021 16:17:46] "POST / HTTP/1.1" 200 -
INFO:root:Origin-->[55.75322, 37.622513] Destination-->[55.747399, 37.841828] Distance(KM)-->[13.743984988551215]
INFO:werkzeug:127.0.0.1 - - [16/Aug/2021 16:17:48] "POST / HTTP/1.1" 200 -
INFO:root:Origin-->[35.12823, 33.149774] Destination-->[55.575816, 37.60107] Distance(KM)-->[2299.6157632824147]
INFO:werkzeug:127.0.0.1 - - [16/Aug/2021 16:17:51] "POST / HTTP/1.1" 200 -
INFO:root:Origin-->[36.885851, 30.701668] Destination-->[55.5778, 37.586536] Distance(KM)-->[2142.9238986128194]
INFO:werkzeug:127.0.0.1 - - [16/Aug/2021 16:17:55] "POST / HTTP/1.1" 200 -
INFO:root:Origin-->[39.920763, 32.854049] Destination-->[55.575816, 37.60107] Distance(KM)-->[1776.0379648356338]
INFO:werkzeug:127.0.0.1 - - [16/Aug/2021 16:22:58] "POST / HTTP/1.1" 200 -
INFO:root:Origin-->[39.749891, 37.015746] Destination-->[55.571999, 37.668911] Distance(KM)-->[1760.4952586044587]
INFO:werkzeug:127.0.0.1 - - [16/Aug/2021 16:30:24] "POST / HTTP/1.1" 200 -
INFO:root:Origin-->[39.920763, 32.854049] Destination-->[55.575816, 37.60107] Distance(KM)-->[1776.0379648356338]
INFO:werkzeug:127.0.0.1 - - [16/Aug/2021 16:47:34] "POST / HTTP/1.1" 200 -
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
requests>=2.26.0
Werkzeug>=1.0.1
Flask>=1.1.2
Jinja2>=2.11.3
90 changes: 90 additions & 0 deletions static/css/error_style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
* {
-webkit-box-sizing: border-box;
box-sizing: border-box;
}

body {
padding: 0;
margin: 0;
}

#notfound {
position: relative;
height: 100vh;
background-color: #222;
}

#notfound .notfound {
position: absolute;
left: 50%;
top: 50%;
-webkit-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}

.notfound {
max-width: 460px;
width: 100%;
text-align: center;
line-height: 1.4;
}

.notfound .notfound-404 {
height: 158px;
line-height: 153px;
}

.notfound .notfound-404 h1 {
font-family: 'Josefin Sans', sans-serif;
color: #222;
font-size: 220px;
letter-spacing: 10px;
margin: 0px;
font-weight: 700;
text-shadow: 2px 2px 0px #c9c9c9, -2px -2px 0px #c9c9c9;
}

.notfound .notfound-404 h1>span {
text-shadow: 2px 2px 0px #ffab00, -2px -2px 0px #ffab00, 0px 0px 8px #ff8700;
}

.notfound p {
font-family: 'Josefin Sans', sans-serif;
color: #c9c9c9;
font-size: 16px;
font-weight: 400;
margin-top: 0px;
margin-bottom: 15px;
}

.notfound a {
font-family: 'Josefin Sans', sans-serif;
font-size: 14px;
text-decoration: none;
text-transform: uppercase;
background: transparent;
color: #c9c9c9;
border: 2px solid #c9c9c9;
display: inline-block;
padding: 10px 25px;
font-weight: 700;
-webkit-transition: 0.2s all;
transition: 0.2s all;
}

.notfound a:hover {
color: #ffab00;
border-color: #ffab00;
}

@media only screen and (max-width: 480px) {
.notfound .notfound-404 {
height: 122px;
line-height: 122px;
}

.notfound .notfound-404 h1 {
font-size: 122px;
}
}
Loading

0 comments on commit 21db007

Please sign in to comment.