22
33import json
44import os
5+ import sqlite3
56
67from flask import (Flask , g , make_response , request , send_from_directory ,
78 url_for )
89from werkzeug .middleware .proxy_fix import ProxyFix
910
11+ from database import Database
1012from provider_dummy import DummyProvider # noqa: F401
13+ from provider_cache import PartsCache
1114from provider_partstack import Partstack
1215
1316app = Flask (__name__ )
@@ -47,6 +50,20 @@ def _write_status(key_values):
4750 app .logger .critical (str (e ))
4851
4952
53+ def _get_db ():
54+ db = getattr (g , '_db' , None )
55+ if db is None :
56+ db = g ._database = sqlite3 .connect ('/config/db.sqlite' )
57+ return db
58+
59+
60+ @app .teardown_appcontext
61+ def _close_db (exception ):
62+ db = getattr (g , '_db' , None )
63+ if db is not None :
64+ db .close ()
65+
66+
5067@app .route ('/api/v1/parts' , methods = ['GET' ])
5168def parts ():
5269 enabled = _get_config ('parts_operational' , False )
@@ -72,21 +89,37 @@ def parts_query():
7289 parts = payload ['parts' ][:PARTS_MAX_COUNT ]
7390 parts = [dict (mpn = p ['mpn' ], manufacturer = p ['manufacturer' ]) for p in parts ]
7491
75- # Fetch parts from provider.
92+ # Prepare database.
93+ db = Database (_get_db (), app .logger )
94+
95+ # Fetch parts from providers.
7696 status = dict ()
77- provider = Partstack (_get_config ('parts_query_url' ),
78- _get_config ('parts_query_token' ),
79- PARTS_QUERY_TIMEOUT , app .logger )
80- provider .fetch (parts , status )
97+ cache_hits = 0
98+ providers = [
99+ PartsCache (db , max_age = 7 * 24 * 3600 ),
100+ Partstack (_get_config ('parts_query_url' ),
101+ _get_config ('parts_query_token' ),
102+ PARTS_QUERY_TIMEOUT , db , app .logger ),
103+ ]
104+ for provider in providers :
105+ cache_hits += provider .fetch (parts , status )
81106
82107 # Handle status changes.
83108 if len (status ):
84109 _write_status (status )
85110
86111 # Complete parts which were not found.
112+ found = 0
87113 for part in parts :
88114 if 'results' not in part :
89115 part ['results' ] = 0
116+ if part ['results' ] > 0 :
117+ found += 1
118+
119+ # Store request in database.
120+ app .logger .debug (f"Queried { len (parts )} parts, { cache_hits } from cache: "
121+ f"{ found } found, { len (parts ) - found } not found" )
122+ db .add_parts_request (len (parts ), cache_hits , found )
90123
91124 # Return response.
92125 return dict (parts = parts )
0 commit comments