implement basic caching mechanism
This commit is contained in:
parent
955bb572a3
commit
17d203575c
1
.gitignore
vendored
1
.gitignore
vendored
@ -5,3 +5,4 @@ __pycache__
|
||||
app-2.2.0.js
|
||||
package-lock.json
|
||||
node_modules
|
||||
_therapydb.cache
|
3
app.py
3
app.py
@ -60,8 +60,7 @@ def search_for_doctors_with_params():
|
||||
# Calculate the required base64 value why so ever
|
||||
base64_value = api_handler.calculate_req_value_base64(float(location_match["lat"]), float(location_match["lon"]))
|
||||
# Get the general list of doctors
|
||||
api_handler.get_list_of_doctors(float(location_match["lat"]), float(location_match["lon"]), base64_value,
|
||||
therapy_types, therapy_age_range, therapy_setting)
|
||||
api_handler.get_list_of_doctors(float(location_match["lat"]), float(location_match["lon"]), base64_value, therapy_types, therapy_age_range, therapy_setting, amount_of_weeks)
|
||||
# Get their information
|
||||
api_handler.get_general_doctor_information()
|
||||
# Filter for the distance
|
||||
|
@ -3,6 +3,7 @@ from typing import List
|
||||
import requests
|
||||
from requests import JSONDecodeError
|
||||
import base64
|
||||
import shelve
|
||||
from datetime import datetime, timedelta
|
||||
from arztapi.ArztPraxisDatas import ArztPraxisDatas
|
||||
from arztapi.DoctorInformation import DoctorInformation, PhoneTime
|
||||
@ -17,10 +18,12 @@ class APIHandler:
|
||||
def __init__(self):
|
||||
# Base URL as given by the base website
|
||||
self.base_api_url = "https://arztsuche.116117.de/api/"
|
||||
self.json_data = {}
|
||||
# Containers for phone times, general doctor information and processed phone times of doctors
|
||||
self.phone_times = []
|
||||
self.general_information = []
|
||||
self.processed_doctor_phone_times = []
|
||||
self._cache = shelve.open("_therapydb.cache")
|
||||
|
||||
def get_lat_lon_location_list(self, location):
|
||||
"""
|
||||
@ -57,34 +60,12 @@ class APIHandler:
|
||||
except JSONDecodeError:
|
||||
return None
|
||||
|
||||
def get_list_of_doctors(self, lat, lon, req_val_base64, therapy_types, therapy_age,
|
||||
therapy_setting) -> ArztPraxisDatas:
|
||||
"""
|
||||
|
||||
:param lat: Latitude as given by location API
|
||||
:param lon: Longitude as given by location API
|
||||
:param req_val_base64: base64 value required for API access (is this a token?)
|
||||
:param therapy_types: Therapy types of interest
|
||||
:param therapy_age: Therapy age range of interest
|
||||
:param therapy_setting: Therapy setting of interest
|
||||
:return: Relevant doctor/therapist data
|
||||
"""
|
||||
|
||||
# API path for doctor data
|
||||
api_path = self.base_api_url + "data"
|
||||
headers = {
|
||||
"Accept": "application/json",
|
||||
"Accept-Language": "de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7",
|
||||
# Authorization header gathered by initial cURLing
|
||||
"Authorization": "Basic YmRwczpma3I0OTNtdmdfZg==",
|
||||
"Connection": "keep-alive",
|
||||
# Calculated base64 value based on latitude and longitude
|
||||
"req-val": req_val_base64,
|
||||
}
|
||||
def get_list_of_doctors(self, lat, lon, req_val_base64, therapy_types, therapy_age, therapy_setting,
|
||||
amount_of_weeks) -> ArztPraxisDatas:
|
||||
|
||||
# Data object as built by the original website, some fields might not be plausible or known (since there is no
|
||||
# API documentation itself available
|
||||
json_data = {
|
||||
self.json_data = {
|
||||
# TODO: Find out what r means
|
||||
"r": 900,
|
||||
"lat": lat,
|
||||
@ -122,7 +103,46 @@ class APIHandler:
|
||||
"viaDeeplink": False,
|
||||
}
|
||||
|
||||
response = requests.post(api_path, headers=headers, json=json_data)
|
||||
amount_of_days = amount_of_weeks * 7
|
||||
cache_data = self.get_current_doctor_information_data_in_cache_with_time_check(amount_of_days)
|
||||
|
||||
if cache_data:
|
||||
print("using cached data")
|
||||
self.phone_times = cache_data
|
||||
|
||||
else:
|
||||
print("call api")
|
||||
self.get_list_of_doctors_from_api(lat, lon, req_val_base64, therapy_types, therapy_age, therapy_setting)
|
||||
self.set_current_doctor_information_data_in_cache()
|
||||
|
||||
def get_list_of_doctors_from_api(self, lat, lon, req_val_base64, therapy_types, therapy_age,
|
||||
therapy_setting) -> ArztPraxisDatas:
|
||||
"""
|
||||
|
||||
:param lat: Latitude as given by location API
|
||||
:param lon: Longitude as given by location API
|
||||
:param req_val_base64: base64 value required for API access (is this a token?)
|
||||
:param therapy_types: Therapy types of interest
|
||||
:param therapy_age: Therapy age range of interest
|
||||
:param therapy_setting: Therapy setting of interest
|
||||
:return: Relevant doctor/therapist data
|
||||
"""
|
||||
|
||||
# API path for doctor data
|
||||
api_path = self.base_api_url + "data"
|
||||
headers = {
|
||||
"Accept": "application/json",
|
||||
"Accept-Language": "de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7",
|
||||
# Authorization header gathered by initial cURLing
|
||||
"Authorization": "Basic YmRwczpma3I0OTNtdmdfZg==",
|
||||
"Connection": "keep-alive",
|
||||
# Calculated base64 value based on latitude and longitude
|
||||
"req-val": req_val_base64,
|
||||
}
|
||||
|
||||
|
||||
|
||||
response = requests.post(api_path, headers=headers, json=self.json_data)
|
||||
# Check for HTTP errors
|
||||
response.raise_for_status()
|
||||
# Convert phone times to data format as input validation, save as class variable for further processing
|
||||
@ -130,6 +150,19 @@ class APIHandler:
|
||||
# Return result for processing by caller
|
||||
return self.phone_times
|
||||
|
||||
def get_current_doctor_information_data_in_cache_with_time_check(self, amount_of_days):
|
||||
cached_data = self._cache.get(str(self.json_data))
|
||||
if cached_data:
|
||||
cache_timestamp = cached_data["timestamp"]
|
||||
current_date = datetime.now()
|
||||
time_difference = current_date - cache_timestamp
|
||||
if time_difference.days <= amount_of_days:
|
||||
return cached_data["data"]
|
||||
|
||||
def set_current_doctor_information_data_in_cache(self):
|
||||
current_date = datetime.now()
|
||||
self._cache[str(self.json_data)] = {"timestamp": current_date, "data": self.phone_times}
|
||||
|
||||
def get_general_doctor_information(self) -> List[DoctorInformation]:
|
||||
"""
|
||||
Transform and filter data to more usable format: Check for phone times and collect general doctor information
|
||||
|
Loading…
Reference in New Issue
Block a user