brian-xetdata commited on
Commit
0af0888
1 Parent(s): f24e0f7

Adding netron and proxy service code

Browse files
Files changed (6) hide show
  1. .gitignore +3 -0
  2. Dockerfile +1 -1
  3. app.py +35 -23
  4. proxy.py +63 -0
  5. requirements.txt +1 -3
  6. wrapper.sh +1 -1
.gitignore CHANGED
@@ -1 +1,4 @@
 
 
1
  .venv
 
 
1
+ __pycache__
2
+
3
  .venv
4
+
Dockerfile CHANGED
@@ -11,4 +11,4 @@ RUN pip install --no-cache-dir --upgrade -r requirements.txt
11
 
12
  COPY --chown=user . /app
13
 
14
- CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
 
11
 
12
  COPY --chown=user . /app
13
 
14
+ CMD "./wrapper.sh"
app.py CHANGED
@@ -1,31 +1,43 @@
1
- from flask import Flask
 
2
 
3
- from starlette.requests import Request
4
- from starlette.responses import StreamingResponse
5
- from starlette.background import BackgroundTask
6
 
7
- import httpx
8
-
9
- client = httpx.AsyncClient(base_url="http://127.0.0.1:8080/")
10
-
11
- async def _reverse_proxy(request: Request):
12
- url = httpx.URL(path=request.url.path,
13
- query=request.url.query.encode("utf-8"))
14
- rp_req = client.build_request(request.method, url,
15
- headers=request.headers.raw,
16
- content=await request.body())
17
- rp_resp = await client.send(rp_req, stream=True)
18
- return StreamingResponse(
19
- rp_resp.aiter_raw(),
20
- status_code=rp_resp.status_code,
21
- headers=rp_resp.headers,
22
- background=BackgroundTask(rp_resp.aclose),
23
- )
24
 
25
  app = Flask(__name__)
26
 
27
- app.add_route("/netron", _reverse_proxy, methods=["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS", "HEAD"])
 
 
 
 
 
 
 
 
 
 
 
28
 
29
  @app.get("/")
30
  def base():
31
- return "<p>Netron is running</p>"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flask import Flask, request, redirect, Response
2
+ import requests
3
 
 
 
 
4
 
5
+ SITE_NAME ="http://127.0.0.1:8080/"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
 
7
  app = Flask(__name__)
8
 
9
+ @app.route('/netron', methods=['GET'])
10
+ def proxy():
11
+ global SITE_NAME
12
+ if request.method=='GET':
13
+ url = request.args.get('url')
14
+ forward = f'{SITE_NAME}?url={url}'
15
+ print(forward)
16
+ resp = requests.get(forward)
17
+ excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection']
18
+ headers = [(name, value) for (name, value) in resp.raw.headers.items() if name.lower() not in excluded_headers]
19
+ response = Response(resp.content, resp.status_code, headers)
20
+ return response
21
 
22
  @app.get("/")
23
  def base():
24
+ return """
25
+ <html>
26
+ <head>
27
+ <title>Netron</title>
28
+ <script type="text/javascript">
29
+ function setFile() {
30
+ console.log("setFile");
31
+ var url = document.getElementById('url').value;
32
+ var iframe = document.getElementById('netron');
33
+ iframe.src = 'http://localhost:7860/?url=' + url;
34
+ }
35
+ </script>
36
+ </head>
37
+ <body style="padding: 0; margin: 0; display: flex; flex-direction: column; align-items: center;">
38
+ <input type="text" id="url" value="https://huggingface.co/brianronan/chessbot-test/resolve/main/chessbot.pb" style="width: 100%; height: 30px;"/>
39
+ <button type="submit" style="width: 100%; height: 30px;" onClick="setFile">Load</button>
40
+ <iframe id="netron" src="http://localhost:7860/?url=https://huggingface.co/brianronan/chessbot-test/resolve/main/chessbot.pb" style="width: 100%; height: 100%; border: none;"/>
41
+ </body>
42
+ </html>
43
+ """
proxy.py ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ #
3
+ from flask import Flask, request, Response
4
+ import requests # pip package requests
5
+
6
+ app = Flask(__name__)
7
+
8
+ API_HOST = "http://127.0.0.1:8080/"
9
+
10
+ # @app.route('/', defaults={'path': ''}, methods=["GET", "POST"]) # ref. https://medium.com/@zwork101/making-a-flask-proxy-server-online-in-10-lines-of-code-44b8721bca6
11
+
12
+ @app.route('/<path>', methods=["GET", "POST"]) # NOTE: better to specify which methods to be accepted. Otherwise, only GET will be accepted. Ref: https://flask.palletsprojects.com/en/3.0.x/quickstart/#http-methods
13
+ def redirect_to_API_HOST(path): #NOTE var :path will be unused as all path we need will be read from :request ie from flask import request
14
+ forward = ''
15
+ if path == 'netron':
16
+ url = request.args.get('url')
17
+ forward = f'{API_HOST}/?url={url}'
18
+ else:
19
+ forward = request.url.replace(request.host_url, f'{API_HOST}/')
20
+
21
+ res = requests.request( # ref. https://stackoverflow.com/a/36601467/248616
22
+ method = request.method,
23
+ url = forward,
24
+ headers = {k:v for k,v in request.headers if k.lower() != 'host'}, # exclude 'host' header
25
+ data = request.get_data(),
26
+ cookies = request.cookies,
27
+ allow_redirects = False,
28
+ )
29
+
30
+ #region exlcude some keys in :res response
31
+ excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection'] #NOTE we here exclude all "hop-by-hop headers" defined by RFC 2616 section 13.5.1 ref. https://www.rfc-editor.org/rfc/rfc2616#section-13.5.1
32
+ headers = [
33
+ (k,v) for k,v in res.raw.headers.items()
34
+ if k.lower() not in excluded_headers
35
+ ]
36
+ #endregion exlcude some keys in :res response
37
+
38
+ response = Response(res.content, res.status_code, headers)
39
+ return response
40
+
41
+ @app.get("/")
42
+ def chooser():
43
+ return """
44
+ <html>
45
+ <head>
46
+ <title>Netron</title>
47
+ <script type="text/javascript">
48
+ function setFile() {
49
+ var url = document.getElementById('url').value;
50
+ var iframe = document.getElementById('netron');
51
+ iframe.src = '/netron?url=' + url;
52
+ }
53
+ </script>
54
+ </head>
55
+ <body style="padding: 0; margin: 0; display: flex; flex-direction: column; align-items: center;">
56
+ <div style="width: 100%; display: flex; flex-direction: row; justify-content: space-between;">
57
+ <input type="text" id="url" value="https://huggingface.co/brianronan/chessbot-test/resolve/main/chessbot.pb" style="width: calc(100% - 100px); height: 30px;"/>
58
+ <button type="submit" style="height: 30px; width: 100px;" onClick="setFile">Load</button>
59
+ </div>
60
+ <iframe id="netron" src="/netron?url=https://huggingface.co/brianronan/chessbot-test/resolve/main/chessbot.pb" style="width: 100%; height: 95%; border: none;"/>
61
+ </body>
62
+ </html>
63
+ """
requirements.txt CHANGED
@@ -1,5 +1,3 @@
1
- fastapi
2
- uvicorn[standard]
3
  flask
4
- httpx
5
  netron
 
 
 
 
1
  flask
 
2
  netron
3
+ requests
wrapper.sh CHANGED
@@ -4,7 +4,7 @@
4
  netron &
5
 
6
  # Start the the web app
7
- uvicorn app:app --host 0.0.0.0 --port 7860 &
8
 
9
  wait -n
10
 
 
4
  netron &
5
 
6
  # Start the the web app
7
+ flask --app proxy run --host 0.0.0.0 --port 7860 &
8
 
9
  wait -n
10