Skip to content

Commit 29e5a22

Browse files
committed
chg: [onion-lookup] query statistics added
1 parent fdca60b commit 29e5a22

File tree

1 file changed

+34
-12
lines changed

1 file changed

+34
-12
lines changed

app.py

+34-12
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from starlette.responses import JSONResponse, RedirectResponse
1111
from starlette.datastructures import URL
1212
from starlette.types import ASGIApp, Receive, Scope, Send
13+
1314
repeated_quotes = re.compile(r'//+') # handling multiple // in url
1415
from urllib.parse import urlparse, unquote
1516
import sys
@@ -18,12 +19,14 @@
1819

1920
# disable requests certificate warning
2021
from requests.packages.urllib3.exceptions import InsecureRequestWarning
22+
2123
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
2224

2325
templates = Jinja2Templates(directory='templates')
2426

2527
# config
2628
import configparser
29+
2730
config = configparser.ConfigParser()
2831
config.read('config.cfg')
2932
ail_url = config['DEFAULT']['ail_url']
@@ -33,6 +36,7 @@
3336
cache = valkey.Valkey(host=valkey_host, port=valkey_port, db=0)
3437
# API definition
3538
from apiman.starlette import Apiman
39+
3640
apiman = Apiman(template="openapi.yml")
3741

3842
if not cache.ping():
@@ -58,6 +62,7 @@ async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
5862
else:
5963
await self.app(scope, receive, send)
6064

65+
6166
def extract_onion_from_url(url):
6267
if not url.startswith('http'):
6368
url = f'http://{url}'
@@ -70,6 +75,18 @@ def extract_onion_from_url(url):
7075
else:
7176
return None
7277

78+
79+
def stats_onion(onion=None, typeo="global"):
80+
if onion is None:
81+
return False
82+
if typeo == "global":
83+
r = cache.zincrby("onion-lookup:stats", 1, onion)
84+
else:
85+
r = cache.zincrby("onion-lookup:ail-stats", 1, onion)
86+
87+
return r
88+
89+
7390
def check_onion(onion=None):
7491
# We only support onion_v3 and automatically append dot onion if missing
7592
if onion is None or onion == '':
@@ -80,19 +97,25 @@ def check_onion(onion=None):
8097
return f"{onion}.onion"
8198
return False
8299

100+
83101
def query_onion(onion=None):
84102
if onion is None:
85103
return False
86104
keycache = f'onion-lookup:{onion}'
105+
stats_onion(onion=onion)
87106
if cache.exists(keycache):
88107
return json.loads(cache.get(keycache))
89-
headers = {'Authorization': ail_apikey}
90-
r = requests.get(f'{ail_url}/api/v1/lookup/onion/{onion}', headers=headers, verify=False)
108+
headers = {'Authorization': ail_apikey}
109+
r = requests.get(
110+
f'{ail_url}/api/v1/lookup/onion/{onion}', headers=headers, verify=False
111+
)
91112
if r.status_code != 200:
92113
return False
93114
cache.set(keycache, r.text, ex=3600)
115+
stats_onion(onion=onion, typeo="local")
94116
return json.loads(cache.get(keycache))
95117

118+
96119
async def homepage(request):
97120
template = "index.html"
98121
context = {"request": request}
@@ -103,12 +126,13 @@ async def homepage(request):
103126
context['onion'] = onion
104127
onion_meta = query_onion(onion=onion)
105128
if onion_meta is not False:
106-
context['onion_meta'] = onion_meta
129+
context['onion_meta'] = onion_meta
107130
else:
108131
context['error'] = 'Incorrect format'
109132

110133
return templates.TemplateResponse(template, context)
111134

135+
112136
@apiman.from_yaml(
113137
"""
114138
summary: lookup api
@@ -123,7 +147,8 @@ async def homepage(request):
123147
responses:
124148
"200":
125149
description: OK
126-
""")
150+
"""
151+
)
127152
async def lookup(request):
128153
onion = extract_onion_from_url(request.path_params['onion'].lower())
129154
onion = check_onion(onion=onion)
@@ -139,9 +164,10 @@ async def lookup(request):
139164

140165
return JSONResponse({})
141166

167+
142168
async def error(request):
143169
"""
144-
Generic catch-call error
170+
Generic catch-call error
145171
"""
146172
raise RuntimeError("Oh no")
147173

@@ -163,23 +189,19 @@ async def server_error(request: Request, exc: HTTPException):
163189
context = {"request": request}
164190
return templates.TemplateResponse(template, context, status_code=500)
165191

192+
166193
routes = [
167194
Route('/', homepage),
168195
Route('/api/lookup/{onion}', lookup, methods=['GET']),
169196
Route('/error', error),
170-
Mount('/static', app=StaticFiles(directory='statics'), name='static')
171-
197+
Mount('/static', app=StaticFiles(directory='statics'), name='static'),
172198
]
173199

174-
exception_handlers = {
175-
404: not_found,
176-
500: server_error
177-
}
200+
exception_handlers = {404: not_found, 500: server_error}
178201

179202
app = Starlette(debug=False, routes=routes, exception_handlers=exception_handlers)
180203
app.add_middleware(HttpUrlRedirectMiddleware)
181204
apiman.init_app(app)
182205

183206
if __name__ == "__main__":
184207
uvicorn.run(app, host='0.0.0.0', port=8000)
185-

0 commit comments

Comments
 (0)