Spaces:
Build error
Build error
Commit
0c40d71
• 1
Parent(s):
03364a4
feat: backend find rework
Browse files- .gitignore +3 -2
- assets/SpaceGrotesk.ttf +0 -0
- assets/SpaceGrotesk.woff2 +0 -0
- assets/find_imag.html +0 -94
- assets/find_lang.html +0 -95
- assets/footer.html +0 -6
- assets/header.html +0 -1
- assets/save_imag.html +0 -26
- assets/save_lang.html +0 -31
- assets/style.css +0 -87
- assets/success.html +0 -11
- backend/main.py +15 -0
- backend/old_main.py +128 -0
- backend/responses.py +92 -0
- backend/security.py +35 -0
- backend/util.py +59 -0
- {.streamlit → frontend/.streamlit}/config.toml +5 -0
- {components → frontend/components}/__pycache__/auth.cpython-38.pyc +0 -0
- {components → frontend/components}/__pycache__/base.cpython-38.pyc +0 -0
- {components → frontend/components}/__pycache__/core.cpython-38.pyc +0 -0
- {components → frontend/components}/__pycache__/custodian.cpython-38.pyc +0 -0
- {components → frontend/components}/__pycache__/header.cpython-38.pyc +0 -0
- {components → frontend/components}/__pycache__/inspector.cpython-38.pyc +0 -0
- {components → frontend/components}/__pycache__/metadata.cpython-38.pyc +0 -0
- {components → frontend/components}/__pycache__/navigator.cpython-38.pyc +0 -0
- {components → frontend/components}/__pycache__/ranker.cpython-38.pyc +0 -0
- {components → frontend/components}/__pycache__/viewport.cpython-38.pyc +0 -0
- {components → frontend/components}/custodian.py +11 -10
- {components → frontend/components}/header.py +0 -0
- {components → frontend/components}/inspector.py +1 -1
- {components → frontend/components}/navigator.py +1 -1
- {components → frontend/components}/ranker.py +0 -0
- {components → frontend/components}/viewport.py +1 -3
- frontend/main.py +65 -0
- knowledge.py +0 -10
- main.py +0 -23
- util.py +39 -2
.gitignore
CHANGED
@@ -1,3 +1,4 @@
|
|
1 |
__pycache__/*
|
2 |
-
|
3 |
-
|
|
1 |
__pycache__/*
|
2 |
+
backend/__pycache__/*
|
3 |
+
knowledge/*
|
4 |
+
backend/records.json
|
assets/SpaceGrotesk.ttf
DELETED
Binary file (137 kB)
|
assets/SpaceGrotesk.woff2
DELETED
Binary file (42.7 kB)
|
assets/find_imag.html
DELETED
@@ -1,94 +0,0 @@
|
|
1 |
-
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"/>
|
2 |
-
<link rel="stylesheet" type="text/css" href="/assets/style.css" media="screen"/>
|
3 |
-
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
|
4 |
-
|
5 |
-
<div class="board" style="position: fixed; top: 33%;">
|
6 |
-
<script> $(function(){$("#header").load("/assets/header.html");}); </script>
|
7 |
-
<div id="header"></div>
|
8 |
-
<form action="/find/imag/html" method="POST" enctype="multipart/form-data">
|
9 |
-
<div class="card">
|
10 |
-
<div class="card-body">Find thoughts by imagery.</div>
|
11 |
-
</div>
|
12 |
-
<br />
|
13 |
-
<div class="card">
|
14 |
-
<div class="card-body">
|
15 |
-
<input type="file" id="file" name="file" accept="image/*" required />
|
16 |
-
</div>
|
17 |
-
</div>
|
18 |
-
<br />
|
19 |
-
<div
|
20 |
-
class="card"
|
21 |
-
style="background-color: var(--background-color); border: 0"
|
22 |
-
>
|
23 |
-
<details>
|
24 |
-
<summary style="color: var(--accent-color)">
|
25 |
-
Customize search parameters...
|
26 |
-
</summary>
|
27 |
-
<table>
|
28 |
-
<tr>
|
29 |
-
<td
|
30 |
-
style="color: var(--accent-color); font-weight: bold"
|
31 |
-
title="Relatedness indicates how important it is for thoughts to be semantically close to the query."
|
32 |
-
>
|
33 |
-
<li>relatedness</li>
|
34 |
-
</td>
|
35 |
-
<td style="width: 10%">
|
36 |
-
<input
|
37 |
-
type="number"
|
38 |
-
style="color: var(--accent-color)"
|
39 |
-
value="1"
|
40 |
-
step="0.01"
|
41 |
-
id="relatedness"
|
42 |
-
name="relatedness"
|
43 |
-
/>
|
44 |
-
</td>
|
45 |
-
</tr>
|
46 |
-
<tr>
|
47 |
-
<td
|
48 |
-
style="color: var(--accent-color); font-weight: bold"
|
49 |
-
title="Serendipity indicates how important it is for thoughts to have low activation."
|
50 |
-
>
|
51 |
-
<li>serendipity</li>
|
52 |
-
</td>
|
53 |
-
<td>
|
54 |
-
<input
|
55 |
-
type="number"
|
56 |
-
style="color: var(--accent-color)"
|
57 |
-
value="0"
|
58 |
-
step="0.01"
|
59 |
-
id="serendipity"
|
60 |
-
name="serendipity"
|
61 |
-
/>
|
62 |
-
</td>
|
63 |
-
</tr>
|
64 |
-
<tr>
|
65 |
-
<td
|
66 |
-
style="color: var(--accent-color); font-weight: bold"
|
67 |
-
title="Noise indicates how much randomness there should be in the results."
|
68 |
-
>
|
69 |
-
<li>noise</li>
|
70 |
-
</td>
|
71 |
-
<td>
|
72 |
-
<input
|
73 |
-
type="number"
|
74 |
-
style="color: var(--accent-color)"
|
75 |
-
value="0.01"
|
76 |
-
step="0.01"
|
77 |
-
id="noise"
|
78 |
-
name="noise"
|
79 |
-
/><br />
|
80 |
-
</td>
|
81 |
-
</tr>
|
82 |
-
</table>
|
83 |
-
</details>
|
84 |
-
</div>
|
85 |
-
<br />
|
86 |
-
<br />
|
87 |
-
<div>
|
88 |
-
<input class="button" type="submit" value="find" />
|
89 |
-
</div>
|
90 |
-
</form>
|
91 |
-
</div>
|
92 |
-
|
93 |
-
<script> $(function(){$("#footer").load("/assets/footer.html");}); </script>
|
94 |
-
<div id="footer"></div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assets/find_lang.html
DELETED
@@ -1,95 +0,0 @@
|
|
1 |
-
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"/>
|
2 |
-
<link rel="stylesheet" type="text/css" href="/assets/style.css" media="screen"/>
|
3 |
-
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
|
4 |
-
|
5 |
-
|
6 |
-
<div class="board" style="position: fixed; top: 33%;">
|
7 |
-
<script> $(function(){$("#header").load("/assets/header.html");}); </script>
|
8 |
-
<div id="header"></div>
|
9 |
-
<form action="/find/lang/html" method="GET">
|
10 |
-
<div class="card">
|
11 |
-
<div class="card-body">Find thoughts by language.</div>
|
12 |
-
</div>
|
13 |
-
<br />
|
14 |
-
<div class="card">
|
15 |
-
<input
|
16 |
-
name="content"
|
17 |
-
id="content"
|
18 |
-
class="card-body card-image"
|
19 |
-
placeholder="Write your query here..."
|
20 |
-
required
|
21 |
-
></input>
|
22 |
-
</div>
|
23 |
-
<br/>
|
24 |
-
<div class="card" style="background-color: var(--background-color); border: 0;">
|
25 |
-
<details>
|
26 |
-
<summary style="color: var(--accent-color);">Customize search parameters...</summary>
|
27 |
-
<table>
|
28 |
-
<tr>
|
29 |
-
<td
|
30 |
-
style="color: var(--accent-color); font-weight: bold"
|
31 |
-
title="Relatedness indicates how important it is for thoughts to be semantically close to the query."
|
32 |
-
>
|
33 |
-
<li>relatedness</li>
|
34 |
-
</td>
|
35 |
-
<td style="width: 10%">
|
36 |
-
<input
|
37 |
-
type="number"
|
38 |
-
style="color: var(--accent-color)"
|
39 |
-
value="1"
|
40 |
-
step="0.01"
|
41 |
-
id="relatedness"
|
42 |
-
name="relatedness"
|
43 |
-
/>
|
44 |
-
</td>
|
45 |
-
</tr>
|
46 |
-
<tr>
|
47 |
-
<td
|
48 |
-
style="color: var(--accent-color); font-weight: bold"
|
49 |
-
title="Serendipity indicates how important it is for thoughts to have low activation."
|
50 |
-
>
|
51 |
-
<li>serendipity</li>
|
52 |
-
</td>
|
53 |
-
<td>
|
54 |
-
<input
|
55 |
-
type="number"
|
56 |
-
style="color: var(--accent-color)"
|
57 |
-
value="0"
|
58 |
-
step="0.01"
|
59 |
-
id="serendipity"
|
60 |
-
name="serendipity"
|
61 |
-
/>
|
62 |
-
</td>
|
63 |
-
</tr>
|
64 |
-
<tr>
|
65 |
-
<td
|
66 |
-
style="color: var(--accent-color); font-weight: bold"
|
67 |
-
title="Noise indicates how much randomness there should be in the results."
|
68 |
-
>
|
69 |
-
<li>noise</li>
|
70 |
-
</td>
|
71 |
-
<td>
|
72 |
-
<input
|
73 |
-
type="number"
|
74 |
-
style="color: var(--accent-color)"
|
75 |
-
value="0.01"
|
76 |
-
step="0.01"
|
77 |
-
id="noise"
|
78 |
-
name="noise"
|
79 |
-
/><br />
|
80 |
-
</td>
|
81 |
-
</tr>
|
82 |
-
</table>
|
83 |
-
</details>
|
84 |
-
|
85 |
-
</div>
|
86 |
-
<br />
|
87 |
-
<br />
|
88 |
-
<div>
|
89 |
-
<input type="submit" value="find" class="button" />
|
90 |
-
</div>
|
91 |
-
</form>
|
92 |
-
</div>
|
93 |
-
|
94 |
-
<script> $(function(){$("#footer").load("/assets/footer.html");}); </script>
|
95 |
-
<div id="footer"></div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assets/footer.html
DELETED
@@ -1,6 +0,0 @@
|
|
1 |
-
<div style="position:fixed; bottom:0; height:auto; margin-top:40px;
|
2 |
-
width:100%; text-align:center; padding-bottom: 1rem;">
|
3 |
-
<a href="https://paulbricman.com/contact"><input type="submit" value="send feedback" class="button" /></a> 
|
4 |
-
<a href="https://github.com/paulbricman/conceptarium#further-reading"><input type="submit" value="learn more" class="button" /></a> 
|
5 |
-
<a href="https://github.com/sponsors/paulbricman"><input type="submit" value="support 🤍" class="button" /></a>
|
6 |
-
</div>
|
|
|
|
|
|
|
|
|
|
|
|
assets/header.html
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
<div class="header"><h2>🌿 conceptarium.</h2></div>
|
|
assets/save_imag.html
DELETED
@@ -1,26 +0,0 @@
|
|
1 |
-
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"/>
|
2 |
-
<link rel="stylesheet" type="text/css" href="/assets/style.css" media="screen"/>
|
3 |
-
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
|
4 |
-
|
5 |
-
<div class="board" style="position: fixed; top: 33%;">
|
6 |
-
<script> $(function(){$("#header").load("/assets/header.html");}); </script>
|
7 |
-
<div id="header"></div>
|
8 |
-
<form action="/save/imag" method="POST" enctype="multipart/form-data">
|
9 |
-
<div class="card">
|
10 |
-
<div class="card-body">Save a thought expressed through imagery.</div>
|
11 |
-
</div>
|
12 |
-
<br />
|
13 |
-
<div class="card">
|
14 |
-
<div class="card-body">
|
15 |
-
<input type="file" id="file" name="file" accept="image/*" required />
|
16 |
-
</div>
|
17 |
-
</div>
|
18 |
-
<br /><br />
|
19 |
-
<div>
|
20 |
-
<input type="submit" value="save" class="button" />
|
21 |
-
</div>
|
22 |
-
</form>
|
23 |
-
</div>
|
24 |
-
|
25 |
-
<script> $(function(){$("#footer").load("/assets/footer.html");}); </script>
|
26 |
-
<div id="footer"></div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assets/save_lang.html
DELETED
@@ -1,31 +0,0 @@
|
|
1 |
-
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"/>
|
2 |
-
<link rel="stylesheet" type="text/css" href="/assets/style.css" media="screen"/>
|
3 |
-
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
|
4 |
-
|
5 |
-
<div class="board" style="position: fixed; top: 33%;">
|
6 |
-
<script> $(function(){$("#header").load("/assets/header.html");}); </script>
|
7 |
-
<div id="header"></div>
|
8 |
-
<form action="/save/lang" method="GET">
|
9 |
-
<div class="board">
|
10 |
-
<div class="card">
|
11 |
-
<div class="card-body">Save a thought expressed in language.</div>
|
12 |
-
</div>
|
13 |
-
<br />
|
14 |
-
<div class="card">
|
15 |
-
<textarea
|
16 |
-
name="content"
|
17 |
-
id="content"
|
18 |
-
class="card-body card-image"
|
19 |
-
required
|
20 |
-
></textarea>
|
21 |
-
</div>
|
22 |
-
<br /><br />
|
23 |
-
<div>
|
24 |
-
<input type="submit" value="save" class="button" />
|
25 |
-
</div>
|
26 |
-
</div>
|
27 |
-
</form>
|
28 |
-
</div>
|
29 |
-
|
30 |
-
<script> $(function(){$("#footer").load("/assets/footer.html");}); </script>
|
31 |
-
<div id="footer"></div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assets/style.css
DELETED
@@ -1,87 +0,0 @@
|
|
1 |
-
:root {
|
2 |
-
--accent-color: #474539;
|
3 |
-
--link-color: #228b22;
|
4 |
-
--text-color: #fffffd;
|
5 |
-
--background-color: #fffffd;
|
6 |
-
}
|
7 |
-
|
8 |
-
@font-face {
|
9 |
-
font-family: "Space Grotesk";
|
10 |
-
src: url("/assets/SpaceGrotesk.ttf") format('truetype'),
|
11 |
-
url("/assets/SpaceGrotesk.woff2") format('woff2');
|
12 |
-
}
|
13 |
-
|
14 |
-
* {
|
15 |
-
box-sizing: border-box;
|
16 |
-
font-family: "Space Grotesk";
|
17 |
-
}
|
18 |
-
|
19 |
-
.board {
|
20 |
-
font-size: 16;
|
21 |
-
width: 100%;
|
22 |
-
text-align: center;
|
23 |
-
margin-bottom: 10px;
|
24 |
-
}
|
25 |
-
|
26 |
-
.header {
|
27 |
-
color: var(--accent-color);
|
28 |
-
text-align: center;
|
29 |
-
}
|
30 |
-
|
31 |
-
.header h2 {
|
32 |
-
font-weight: bold;
|
33 |
-
margin: 20px;
|
34 |
-
font-size: 3rem;
|
35 |
-
color: var(--accent-color);
|
36 |
-
}
|
37 |
-
|
38 |
-
body {
|
39 |
-
background-color: var(--text-color);
|
40 |
-
}
|
41 |
-
|
42 |
-
.card-image {
|
43 |
-
width: 100%;
|
44 |
-
}
|
45 |
-
|
46 |
-
.button {
|
47 |
-
width: fit-content;
|
48 |
-
border: 4px solid;
|
49 |
-
border-color: var(--link-color);
|
50 |
-
border-radius: 4px;
|
51 |
-
background-color: var(--link-color);
|
52 |
-
color: var(--text-color);
|
53 |
-
font-weight: bold;
|
54 |
-
padding-left: 10px;
|
55 |
-
padding-right: 10px;
|
56 |
-
}
|
57 |
-
|
58 |
-
.card {
|
59 |
-
box-sizing: border-box;
|
60 |
-
border: 4px solid;
|
61 |
-
border-color: var(--accent-color);
|
62 |
-
background-color: var(--accent-color);
|
63 |
-
display: inline-block;
|
64 |
-
margin: 10px;
|
65 |
-
margin-bottom: 0px;
|
66 |
-
width: 40rem;
|
67 |
-
color: var(--text-color);
|
68 |
-
font-weight: bold;
|
69 |
-
text-align: left;
|
70 |
-
}
|
71 |
-
|
72 |
-
@media only screen and (max-width: 1200px) {
|
73 |
-
.card {
|
74 |
-
width: calc(100% - 40px);
|
75 |
-
margin: 20px;
|
76 |
-
margin-bottom: 0px;
|
77 |
-
font-size: 1.5rem !important;
|
78 |
-
}
|
79 |
-
|
80 |
-
.button {
|
81 |
-
font-size: 1.5rem !important;
|
82 |
-
}
|
83 |
-
|
84 |
-
.header h2 {
|
85 |
-
font-size: 3rem !important;
|
86 |
-
}
|
87 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assets/success.html
DELETED
@@ -1,11 +0,0 @@
|
|
1 |
-
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"/>
|
2 |
-
<link rel="stylesheet" type="text/css" href="/assets/style.css" media="screen"/>
|
3 |
-
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
|
4 |
-
|
5 |
-
<div class="board" style="position: fixed; top: 33%;">
|
6 |
-
<script> $(function(){$("#header").load("/assets/header.html");}); </script>
|
7 |
-
<div id="header"></div>
|
8 |
-
<div class="card">
|
9 |
-
<div class="card-body">Thought saved successfully.</div>
|
10 |
-
</div>
|
11 |
-
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
backend/main.py
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from fastapi import FastAPI
|
2 |
+
from security import auth
|
3 |
+
from util import find
|
4 |
+
from sentence_transformers import SentenceTransformer
|
5 |
+
|
6 |
+
|
7 |
+
app = FastAPI()
|
8 |
+
encoder_model = SentenceTransformer('clip-ViT-B-32')
|
9 |
+
|
10 |
+
|
11 |
+
@app.get('/find')
|
12 |
+
async def find_handler(query: str, token: str):
|
13 |
+
auth_result = auth(token)
|
14 |
+
results = find('text', query, auth_result, encoder_model)
|
15 |
+
return results
|
backend/old_main.py
ADDED
@@ -0,0 +1,128 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from fastapi import FastAPI, File, BackgroundTasks
|
2 |
+
from fastapi.datastructures import UploadFile
|
3 |
+
from fastapi.staticfiles import StaticFiles
|
4 |
+
from fastapi.responses import HTMLResponse, PlainTextResponse, FileResponse
|
5 |
+
import secrets
|
6 |
+
from pathlib import Path
|
7 |
+
from typing import Optional
|
8 |
+
from PIL import Image
|
9 |
+
import io
|
10 |
+
|
11 |
+
from fastapi.old_util import *
|
12 |
+
from responses import *
|
13 |
+
|
14 |
+
app = FastAPI()
|
15 |
+
model = load_model()
|
16 |
+
init()
|
17 |
+
|
18 |
+
app.mount('/conceptarium', StaticFiles(directory='conceptarium'))
|
19 |
+
app.mount('/assets', StaticFiles(directory='assets'))
|
20 |
+
|
21 |
+
|
22 |
+
@app.get('/save/lang/form')
|
23 |
+
async def save_language_form():
|
24 |
+
return HTMLResponse(save_lang_form_response())
|
25 |
+
|
26 |
+
|
27 |
+
@app.get('/save/imag/form')
|
28 |
+
async def save_imagery_form():
|
29 |
+
return HTMLResponse(save_imag_form_response())
|
30 |
+
|
31 |
+
|
32 |
+
@app.get('/save/lang')
|
33 |
+
async def save_language(content: str, background_tasks: BackgroundTasks):
|
34 |
+
if len(content) > 0:
|
35 |
+
filename = 'conceptarium/' + secrets.token_urlsafe(8) + '.txt'
|
36 |
+
open(filename, 'w').write(content)
|
37 |
+
background_tasks.add_task(save, Thought(filename, content, model))
|
38 |
+
return HTMLResponse(save_success_response())
|
39 |
+
|
40 |
+
|
41 |
+
@app.post('/save/imag')
|
42 |
+
async def save_imagery(file: UploadFile = File(...)):
|
43 |
+
content = await file.read()
|
44 |
+
image = Image.open(io.BytesIO(content)).convert('RGB')
|
45 |
+
filename = 'conceptarium/' + secrets.token_urlsafe(8) + '.jpg'
|
46 |
+
image.save(filename, quality=50)
|
47 |
+
save(Thought(filename, content, model))
|
48 |
+
return HTMLResponse(save_success_response())
|
49 |
+
|
50 |
+
|
51 |
+
@app.get('/find/lang/form')
|
52 |
+
async def find_by_language_form():
|
53 |
+
return HTMLResponse(find_lang_form_response())
|
54 |
+
|
55 |
+
|
56 |
+
@app.get('/find/lang/html')
|
57 |
+
async def find_by_language_return_html(content: str, relatedness: Optional[float] = 1, serendipity: Optional[float] = 0, noise: Optional[float] = 0.01, silent: Optional[bool] = False, top_k: Optional[int] = 50):
|
58 |
+
thoughts = find(content, model, relatedness,
|
59 |
+
serendipity, noise, silent, top_k)
|
60 |
+
return HTMLResponse(html_response(thoughts))
|
61 |
+
|
62 |
+
|
63 |
+
@app.get('/find/lang/text')
|
64 |
+
async def find_by_language_return_plaintext(content: str, relatedness: Optional[float] = 1, serendipity: Optional[float] = 0, noise: Optional[float] = 0.01, silent: Optional[bool] = False, top_k: Optional[int] = 50):
|
65 |
+
thoughts = find(content, model, relatedness,
|
66 |
+
serendipity, noise, silent, top_k)
|
67 |
+
return PlainTextResponse(plaintext_response(thoughts))
|
68 |
+
|
69 |
+
|
70 |
+
@app.get('/find/lang/file')
|
71 |
+
async def find_by_language_return_file(content: str, relatedness: Optional[float] = 1, serendipity: Optional[float] = 0, noise: Optional[float] = 0.01, silent: Optional[bool] = False, top_k: Optional[int] = 50):
|
72 |
+
thoughts = find(content, model, relatedness,
|
73 |
+
serendipity, noise, silent, top_k)
|
74 |
+
return FileResponse(file_response(thoughts))
|
75 |
+
|
76 |
+
|
77 |
+
@app.get('/find/lang/json')
|
78 |
+
async def find_by_language_return_json(content: str, relatedness: Optional[float] = 1, serendipity: Optional[float] = 0, noise: Optional[float] = 0.01, silent: Optional[bool] = False, top_k: Optional[int] = 50):
|
79 |
+
thoughts = find(content, model, relatedness,
|
80 |
+
serendipity, noise, silent, top_k)
|
81 |
+
return json_response(thoughts)
|
82 |
+
|
83 |
+
|
84 |
+
@app.get('/find/imag/form')
|
85 |
+
async def find_by_imagery_form():
|
86 |
+
return HTMLResponse(find_imag_form_response())
|
87 |
+
|
88 |
+
|
89 |
+
@app.post('/find/imag/html')
|
90 |
+
async def find_by_imagery_return_html(file: UploadFile = File(...), relatedness: Optional[float] = 1, serendipity: Optional[float] = 0, noise: Optional[float] = 0.01, silent: Optional[bool] = False, top_k: Optional[int] = 50):
|
91 |
+
content = await file.read()
|
92 |
+
thoughts = find(content, model, relatedness,
|
93 |
+
serendipity, noise, silent, top_k)
|
94 |
+
return HTMLResponse(html_response(thoughts))
|
95 |
+
|
96 |
+
|
97 |
+
@app.post('/find/imag/text')
|
98 |
+
async def find_by_imagery_return_plaintext(file: UploadFile = File(...), relatedness: Optional[float] = 1, serendipity: Optional[float] = 0, noise: Optional[float] = 0.01, silent: Optional[bool] = False, top_k: Optional[int] = 50):
|
99 |
+
content = await file.read()
|
100 |
+
thoughts = find(content, model, relatedness,
|
101 |
+
serendipity, noise, silent, top_k)
|
102 |
+
return PlainTextResponse(plaintext_response(thoughts))
|
103 |
+
|
104 |
+
|
105 |
+
@app.post('/find/imag/file')
|
106 |
+
async def find_by_imagery_return_file(file: UploadFile = File(...), relatedness: Optional[float] = 1, serendipity: Optional[float] = 0, noise: Optional[float] = 0.01, silent: Optional[bool] = False, top_k: Optional[int] = 50):
|
107 |
+
content = await file.read()
|
108 |
+
thoughts = find(content, model, relatedness,
|
109 |
+
serendipity, noise, silent, top_k)
|
110 |
+
return FileResponse(file_response(thoughts))
|
111 |
+
|
112 |
+
|
113 |
+
@app.post('/find/imag/json')
|
114 |
+
async def find_by_imagery_return_json(file: UploadFile = File(...), relatedness: Optional[float] = 1, serendipity: Optional[float] = 0, noise: Optional[float] = 0.01, silent: Optional[bool] = False, top_k: Optional[int] = 50):
|
115 |
+
content = await file.read()
|
116 |
+
thoughts = find(content, model, relatedness,
|
117 |
+
serendipity, noise, silent, top_k)
|
118 |
+
return json_response(thoughts)
|
119 |
+
|
120 |
+
|
121 |
+
@app.get('/rset/embs')
|
122 |
+
async def reset_embeddings_handle():
|
123 |
+
reset_embeddings(model)
|
124 |
+
|
125 |
+
|
126 |
+
@app.get('/dump')
|
127 |
+
async def dump_conceptarium():
|
128 |
+
return FileResponse(archive_response(), filename='conceptarium.zip')
|
backend/responses.py
ADDED
@@ -0,0 +1,92 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from fastapi.old_util import get_doc_paths
|
2 |
+
from zipfile import ZipFile
|
3 |
+
import numpy as np
|
4 |
+
import time
|
5 |
+
|
6 |
+
|
7 |
+
def html_response(thoughts):
|
8 |
+
html = '<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">'
|
9 |
+
html += '<link rel="stylesheet" type="text/css" href="/assets/style.css" media="screen" />'
|
10 |
+
html += '<script src="//code.jquery.com/jquery-1.10.2.js"></script>'
|
11 |
+
html += '<script> $(function(){$("#header").load("/assets/header.html");}); </script>'
|
12 |
+
html += '<div id="header""></div><div class="board">'
|
13 |
+
|
14 |
+
for thought in thoughts:
|
15 |
+
html += '<div class="card">'
|
16 |
+
if thought.modality == 'language':
|
17 |
+
content = open(thought.filename, 'r').read()
|
18 |
+
html += '<div class="card-body">' + content + '</div>'
|
19 |
+
else:
|
20 |
+
html += '<img class="card-img" src=\"/' + \
|
21 |
+
thought.filename + '\">'
|
22 |
+
html += '</div><br/>'
|
23 |
+
|
24 |
+
html += '</div>'
|
25 |
+
return html
|
26 |
+
|
27 |
+
|
28 |
+
def save_success_response():
|
29 |
+
return open('assets/success.html').read()
|
30 |
+
|
31 |
+
|
32 |
+
def save_lang_form_response():
|
33 |
+
return open('assets/save_lang.html').read()
|
34 |
+
|
35 |
+
|
36 |
+
def save_imag_form_response():
|
37 |
+
return open('assets/save_imag.html').read()
|
38 |
+
|
39 |
+
|
40 |
+
def find_lang_form_response():
|
41 |
+
return open('assets/find_lang.html').read()
|
42 |
+
|
43 |
+
|
44 |
+
def find_imag_form_response():
|
45 |
+
return open('assets/find_imag.html').read()
|
46 |
+
|
47 |
+
|
48 |
+
def archive_response():
|
49 |
+
paths = get_doc_paths('conceptarium')
|
50 |
+
with ZipFile('conceptarium.zip', 'w') as zip:
|
51 |
+
for path in paths:
|
52 |
+
zip.write(path)
|
53 |
+
|
54 |
+
return 'conceptarium.zip'
|
55 |
+
|
56 |
+
|
57 |
+
def plaintext_response(thoughts):
|
58 |
+
plaintext = ''
|
59 |
+
|
60 |
+
for thought in thoughts:
|
61 |
+
if thought.modality == 'language':
|
62 |
+
content = open(thought.filename, 'r').read()
|
63 |
+
plaintext += '\"' + content + '\"\n'
|
64 |
+
|
65 |
+
return plaintext
|
66 |
+
|
67 |
+
|
68 |
+
def file_response(thoughts):
|
69 |
+
for thought in thoughts:
|
70 |
+
if thought.modality == 'imagery':
|
71 |
+
return thought.filename
|
72 |
+
|
73 |
+
|
74 |
+
def json_response(thoughts):
|
75 |
+
response_json = []
|
76 |
+
|
77 |
+
for thought in thoughts:
|
78 |
+
thought_json = {
|
79 |
+
'timestamp': thought.timestamp,
|
80 |
+
'interest': thought.interest,
|
81 |
+
'activation': np.log(thought.interest / (1 - 0.9)) - 0.9 * np.log((time.time() - thought.timestamp) / (3600 * 24) + 0.1),
|
82 |
+
'modality': thought.modality,
|
83 |
+
'embedding': thought.embedding.tolist(),
|
84 |
+
}
|
85 |
+
|
86 |
+
if thought.modality == 'language':
|
87 |
+
thought_json['content'] = open(thought.filename, 'r').read()
|
88 |
+
else:
|
89 |
+
thought_json['filename'] = '/' + thought.filename
|
90 |
+
|
91 |
+
response_json += [thought_json]
|
92 |
+
return response_json
|
backend/security.py
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from pathlib import Path
|
2 |
+
import json
|
3 |
+
import bcrypt
|
4 |
+
|
5 |
+
|
6 |
+
def auth(token):
|
7 |
+
path = Path('records.json')
|
8 |
+
|
9 |
+
if not path.exists():
|
10 |
+
salt = bcrypt.gensalt()
|
11 |
+
hashed_token = bcrypt.hashpw(token.encode(
|
12 |
+
'utf8'), salt).decode('utf8')
|
13 |
+
|
14 |
+
records = {
|
15 |
+
'custodian_hashed_token': hashed_token,
|
16 |
+
'custodian_hashed_token_salt': salt.decode('utf8')
|
17 |
+
}
|
18 |
+
json.dump(records, open(path, 'w'))
|
19 |
+
|
20 |
+
return {
|
21 |
+
'custodian': True
|
22 |
+
}
|
23 |
+
else:
|
24 |
+
records = json.load(open(path))
|
25 |
+
hashed_token = bcrypt.hashpw(token.encode(
|
26 |
+
'utf-8'), records['custodian_hashed_token_salt'].encode('utf8')).decode('utf8')
|
27 |
+
|
28 |
+
if records['custodian_hashed_token'] == hashed_token:
|
29 |
+
return {
|
30 |
+
'custodian': True
|
31 |
+
}
|
32 |
+
else:
|
33 |
+
return {
|
34 |
+
'custodian': False
|
35 |
+
}
|
backend/util.py
ADDED
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import json
|
2 |
+
from pathlib import Path
|
3 |
+
from PIL import Image
|
4 |
+
import io
|
5 |
+
from sentence_transformers import util
|
6 |
+
import torch
|
7 |
+
import base64
|
8 |
+
|
9 |
+
|
10 |
+
def find(modality, query, auth_result, encoder_model):
|
11 |
+
authorized_thoughts = get_authorized_thoughts(auth_result)
|
12 |
+
|
13 |
+
if len(authorized_thoughts) == 0:
|
14 |
+
return []
|
15 |
+
|
16 |
+
query_embedding = torch.Tensor([embed(modality, query, encoder_model)])
|
17 |
+
print('query_embedding.size()', query_embedding.size())
|
18 |
+
corpus_embeddings = torch.Tensor(
|
19 |
+
[e['embedding'] for e in authorized_thoughts])
|
20 |
+
results = util.semantic_search(
|
21 |
+
query_embedding, corpus_embeddings, top_k=10 ** 10)
|
22 |
+
|
23 |
+
for e in results[0]:
|
24 |
+
authorized_thoughts[e['corpus_id']]['relatedness'] = e['score']
|
25 |
+
authorized_thoughts[e['corpus_id']]['content'] = get_content(
|
26 |
+
authorized_thoughts[e['corpus_id']])
|
27 |
+
authorized_thoughts[e['corpus_id']].pop('filename', None)
|
28 |
+
|
29 |
+
return authorized_thoughts
|
30 |
+
|
31 |
+
|
32 |
+
def get_authorized_thoughts(auth_result):
|
33 |
+
metadata_path = Path('..') / 'knowledge' / 'base' / 'metadata.json'
|
34 |
+
|
35 |
+
if auth_result['custodian'] == True:
|
36 |
+
return json.load(open(metadata_path))
|
37 |
+
else:
|
38 |
+
return []
|
39 |
+
|
40 |
+
|
41 |
+
def embed(modality, content, encoder_model):
|
42 |
+
if modality == 'text':
|
43 |
+
return encoder_model.encode(content)
|
44 |
+
elif modality == 'image':
|
45 |
+
return encoder_model.encode(Image.open(io.BytesIO(content)))
|
46 |
+
|
47 |
+
|
48 |
+
def get_content(thought, json_friendly=False):
|
49 |
+
knowledge_base_path = Path('..') / 'knowledge' / 'base'
|
50 |
+
|
51 |
+
if thought['modality'] == 'text':
|
52 |
+
content = open(knowledge_base_path / thought['filename']).read()
|
53 |
+
elif thought['modality'] == 'image':
|
54 |
+
content = open(knowledge_base_path / thought['filename'], 'rb').read()
|
55 |
+
|
56 |
+
if json_friendly:
|
57 |
+
content = base64.encodebytes(content).decode('utf8')
|
58 |
+
|
59 |
+
return content
|
{.streamlit → frontend/.streamlit}/config.toml
RENAMED
@@ -2,3 +2,8 @@
|
|
2 |
base="light"
|
3 |
primaryColor="#228b22"
|
4 |
font="monospace"
|
|
|
|
|
|
|
|
|
|
2 |
base="light"
|
3 |
primaryColor="#228b22"
|
4 |
font="monospace"
|
5 |
+
|
6 |
+
[server]
|
7 |
+
enableCORS = false
|
8 |
+
enableXsrfProtection = false
|
9 |
+
headless = true
|
{components → frontend/components}/__pycache__/auth.cpython-38.pyc
RENAMED
File without changes
|
{components → frontend/components}/__pycache__/base.cpython-38.pyc
RENAMED
File without changes
|
{components → frontend/components}/__pycache__/core.cpython-38.pyc
RENAMED
File without changes
|
{components → frontend/components}/__pycache__/custodian.cpython-38.pyc
RENAMED
Binary files a/components/__pycache__/custodian.cpython-38.pyc and b/frontend/components/__pycache__/custodian.cpython-38.pyc differ
|
{components → frontend/components}/__pycache__/header.cpython-38.pyc
RENAMED
File without changes
|
{components → frontend/components}/__pycache__/inspector.cpython-38.pyc
RENAMED
File without changes
|
{components → frontend/components}/__pycache__/metadata.cpython-38.pyc
RENAMED
File without changes
|
{components → frontend/components}/__pycache__/navigator.cpython-38.pyc
RENAMED
File without changes
|
{components → frontend/components}/__pycache__/ranker.cpython-38.pyc
RENAMED
File without changes
|
{components → frontend/components}/__pycache__/viewport.cpython-38.pyc
RENAMED
Binary files a/components/__pycache__/viewport.cpython-38.pyc and b/frontend/components/__pycache__/viewport.cpython-38.pyc differ
|
{components → frontend/components}/custodian.py
RENAMED
@@ -9,11 +9,12 @@ def paint():
|
|
9 |
st.markdown('#### 📜 custodian')
|
10 |
|
11 |
if not os.path.exists('records/custodian.json'):
|
12 |
-
st.warning(
|
13 |
-
|
|
|
14 |
username = st.text_input('Username')
|
15 |
password = st.text_input('Password', type='password')
|
16 |
-
|
17 |
if st.button('create account'):
|
18 |
password = stauth.hasher([password]).generate()[0]
|
19 |
token = stauth.hasher([password + 'token']).generate()[0]
|
@@ -24,13 +25,13 @@ def paint():
|
|
24 |
}, open('records/custodian.json', 'w'))
|
25 |
st.balloons()
|
26 |
else:
|
27 |
-
st.warning(
|
|
|
28 |
custodian = json.load(open('records/custodian.json'))
|
29 |
-
authenticator = stauth.authenticate([custodian['username']], [custodian['username']]
|
30 |
-
|
31 |
-
name, authentication_status = authenticator.login(
|
32 |
-
|
33 |
-
print(name, authentication_status)
|
34 |
|
35 |
if st.session_state['authentication_status']:
|
36 |
st.markdown('')
|
@@ -39,4 +40,4 @@ def paint():
|
|
39 |
elif st.session_state['authentication_status'] == False:
|
40 |
st.error('Username/password is incorrect')
|
41 |
elif st.session_state['authentication_status'] == None:
|
42 |
-
st.warning('Please enter your username and password')
|
9 |
st.markdown('#### 📜 custodian')
|
10 |
|
11 |
if not os.path.exists('records/custodian.json'):
|
12 |
+
st.warning(
|
13 |
+
'This appears to be a fresh conceptarium instance. Please create a custodian account.')
|
14 |
+
|
15 |
username = st.text_input('Username')
|
16 |
password = st.text_input('Password', type='password')
|
17 |
+
|
18 |
if st.button('create account'):
|
19 |
password = stauth.hasher([password]).generate()[0]
|
20 |
token = stauth.hasher([password + 'token']).generate()[0]
|
25 |
}, open('records/custodian.json', 'w'))
|
26 |
st.balloons()
|
27 |
else:
|
28 |
+
st.warning(
|
29 |
+
'If you\'re the custodian of this conceptarium, please log into your account to access your stored thoughts.')
|
30 |
custodian = json.load(open('records/custodian.json'))
|
31 |
+
authenticator = stauth.authenticate([custodian['username']], [custodian['username']], [custodian['password']],
|
32 |
+
'custodian_cookie', 'conceptarium', cookie_expiry_days=30)
|
33 |
+
name, authentication_status = authenticator.login(
|
34 |
+
'login', 'sidebar')
|
|
|
35 |
|
36 |
if st.session_state['authentication_status']:
|
37 |
st.markdown('')
|
40 |
elif st.session_state['authentication_status'] == False:
|
41 |
st.error('Username/password is incorrect')
|
42 |
elif st.session_state['authentication_status'] == None:
|
43 |
+
st.warning('Please enter your username and password')
|
{components → frontend/components}/header.py
RENAMED
File without changes
|
{components → frontend/components}/inspector.py
RENAMED
@@ -1,5 +1,5 @@
|
|
1 |
import streamlit as st
|
2 |
-
import knowledge
|
3 |
from datetime import datetime
|
4 |
import numpy as np
|
5 |
import time
|
1 |
import streamlit as st
|
2 |
+
import knowledge.knowledge as knowledge
|
3 |
from datetime import datetime
|
4 |
import numpy as np
|
5 |
import time
|
{components → frontend/components}/navigator.py
RENAMED
@@ -3,7 +3,7 @@ from sentence_transformers import SentenceTransformer
|
|
3 |
import io
|
4 |
from PIL import Image
|
5 |
import torch
|
6 |
-
import knowledge
|
7 |
|
8 |
|
9 |
def get_name():
|
3 |
import io
|
4 |
from PIL import Image
|
5 |
import torch
|
6 |
+
import knowledge.knowledge as knowledge
|
7 |
|
8 |
|
9 |
def get_name():
|
{components → frontend/components}/ranker.py
RENAMED
File without changes
|
{components → frontend/components}/viewport.py
RENAMED
@@ -1,5 +1,5 @@
|
|
1 |
import streamlit as st
|
2 |
-
import knowledge
|
3 |
from sentence_transformers import util
|
4 |
import torch
|
5 |
import numpy as np
|
@@ -17,8 +17,6 @@ def load_thoughts():
|
|
17 |
imagery_centroid = torch.mean(torch.stack(
|
18 |
[e.embedding for e in thoughts if e.modality == 'imagery']), -2)
|
19 |
|
20 |
-
print(imagery_centroid - langauge_centroid)
|
21 |
-
|
22 |
for thought_idx, thought in enumerate(thoughts):
|
23 |
if thought.modality == 'imagery':
|
24 |
thoughts[thought_idx].embedding += langauge_centroid - \
|
1 |
import streamlit as st
|
2 |
+
import knowledge.knowledge as knowledge
|
3 |
from sentence_transformers import util
|
4 |
import torch
|
5 |
import numpy as np
|
17 |
imagery_centroid = torch.mean(torch.stack(
|
18 |
[e.embedding for e in thoughts if e.modality == 'imagery']), -2)
|
19 |
|
|
|
|
|
20 |
for thought_idx, thought in enumerate(thoughts):
|
21 |
if thought.modality == 'imagery':
|
22 |
thoughts[thought_idx].embedding += langauge_centroid - \
|
frontend/main.py
ADDED
@@ -0,0 +1,65 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
from components import custodian, header, inspector, navigator, viewport, ranker
|
3 |
+
import uvicorn
|
4 |
+
|
5 |
+
|
6 |
+
st.set_page_config(
|
7 |
+
page_title='💡 conceptarium',
|
8 |
+
layout='wide',
|
9 |
+
menu_items={
|
10 |
+
'About': 'hello world'
|
11 |
+
})
|
12 |
+
|
13 |
+
|
14 |
+
# if not hasattr(st, 'already_started_server'):
|
15 |
+
# # Hack the fact that Python modules (like st) only load once to
|
16 |
+
# # keep track of whether this file already ran.
|
17 |
+
# st.already_started_server = True
|
18 |
+
|
19 |
+
# st.write('''
|
20 |
+
# The first time this script executes it will run forever because it's
|
21 |
+
# running a Flask server.
|
22 |
+
|
23 |
+
# Just close this browser tab and open a new one to see your Streamlit
|
24 |
+
# app.
|
25 |
+
# ''')
|
26 |
+
|
27 |
+
# from flask import Flask
|
28 |
+
|
29 |
+
# app = Flask(__name__)
|
30 |
+
|
31 |
+
# @app.route('/foo')
|
32 |
+
# def serve_foo():
|
33 |
+
# return 'This page is served via Flask!' + str(st.session_state['authentication_status'])
|
34 |
+
|
35 |
+
# app.run(port=8888)
|
36 |
+
|
37 |
+
# # from fastapi import FastAPI
|
38 |
+
|
39 |
+
# # app = FastAPI()
|
40 |
+
|
41 |
+
# # @app.get("/")
|
42 |
+
# # async def root():
|
43 |
+
# # return {"message": "Hello World"}
|
44 |
+
|
45 |
+
# # print('running next')
|
46 |
+
# # uvicorn.run(app, port=8888)
|
47 |
+
# # print('ran')
|
48 |
+
|
49 |
+
|
50 |
+
custodian.paint()
|
51 |
+
header.paint()
|
52 |
+
|
53 |
+
cols = st.columns(5)
|
54 |
+
|
55 |
+
for component in [navigator, ranker]:
|
56 |
+
with cols[0]:
|
57 |
+
with st.expander(component.get_name(), True):
|
58 |
+
component.paint()
|
59 |
+
|
60 |
+
for component in [inspector]:
|
61 |
+
with cols[-1]:
|
62 |
+
with st.expander(component.get_name(), True):
|
63 |
+
component.paint()
|
64 |
+
|
65 |
+
viewport.paint(cols[1:-1])
|
knowledge.py
DELETED
@@ -1,10 +0,0 @@
|
|
1 |
-
import streamlit as st
|
2 |
-
import pickle
|
3 |
-
|
4 |
-
|
5 |
-
def load():
|
6 |
-
if st.session_state['authentication_status']:
|
7 |
-
thoughts = pickle.load(open('conceptarium/metadata.pickle', 'rb'))
|
8 |
-
return thoughts
|
9 |
-
else:
|
10 |
-
return []
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
main.py
DELETED
@@ -1,23 +0,0 @@
|
|
1 |
-
import streamlit as st
|
2 |
-
from components import custodian, header, inspector, navigator, viewport, ranker
|
3 |
-
|
4 |
-
st.set_page_config(
|
5 |
-
page_title='💡 conceptarium',
|
6 |
-
layout='wide')
|
7 |
-
|
8 |
-
custodian.paint()
|
9 |
-
header.paint()
|
10 |
-
|
11 |
-
cols = st.columns(5)
|
12 |
-
|
13 |
-
for component in [navigator, ranker]:
|
14 |
-
with cols[0]:
|
15 |
-
with st.expander(component.get_name(), True):
|
16 |
-
component.paint()
|
17 |
-
|
18 |
-
for component in [inspector]:
|
19 |
-
with cols[-1]:
|
20 |
-
with st.expander(component.get_name(), True):
|
21 |
-
component.paint()
|
22 |
-
|
23 |
-
viewport.paint(cols[1:-1])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
util.py
CHANGED
@@ -123,9 +123,46 @@ class Thought:
|
|
123 |
self.interest = 1
|
124 |
self.embedding = embed(content, model)
|
125 |
|
126 |
-
|
127 |
def get_content(self):
|
128 |
if self.modality == 'language':
|
129 |
return open(self.filename).read()
|
130 |
elif self.modality == 'imagery':
|
131 |
-
return open(self.filename, 'rb').read()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
123 |
self.interest = 1
|
124 |
self.embedding = embed(content, model)
|
125 |
|
|
|
126 |
def get_content(self):
|
127 |
if self.modality == 'language':
|
128 |
return open(self.filename).read()
|
129 |
elif self.modality == 'imagery':
|
130 |
+
return open(self.filename, 'rb').read()
|
131 |
+
|
132 |
+
|
133 |
+
'''
|
134 |
+
import json
|
135 |
+
thoughts = json.load(open('knowledge/base/metadata.json', 'rb'))
|
136 |
+
|
137 |
+
from datetime import datetime
|
138 |
+
new_thoughts = []
|
139 |
+
for thought in thoughts:
|
140 |
+
new_thought = {}
|
141 |
+
new_thought['filename'] = thought.filename
|
142 |
+
new_thought['modality'] = thought.modality
|
143 |
+
new_thought['timestamp'] = thought.timestamp
|
144 |
+
new_thought['interest'] = thought.interest
|
145 |
+
new_thought['embedding'] = thought.embedding
|
146 |
+
new_thoughts += [new_thought]
|
147 |
+
|
148 |
+
for e_idx, e in enumerate(new_thoughts):
|
149 |
+
if e['modality'] == 'language':
|
150 |
+
new_thoughts[e_idx]['modality'] = 'text'
|
151 |
+
elif e['modality'] == 'imagery':
|
152 |
+
new_thoughts[e_idx]['modality'] = 'image'
|
153 |
+
else:
|
154 |
+
print(e['modality'])
|
155 |
+
|
156 |
+
for e_idx, e in enumerate(new_thoughts):
|
157 |
+
new_thoughts[e_idx]['embedding'] = e['embedding'].tolist()
|
158 |
+
|
159 |
+
for e_idx, e in enumerate(new_thoughts):
|
160 |
+
new_thoughts[e_idx]['embedding'] = [round(f, 6) for f in e['embedding']]
|
161 |
+
|
162 |
+
for e_idx, e in enumerate(new_thoughts):
|
163 |
+
new_thoughts[e_idx]['filename'] = e['filename'].split('/')[-1]
|
164 |
+
|
165 |
+
new_thoughts[0]
|
166 |
+
|
167 |
+
json.dump(new_thoughts, open('knowledge/base/metadata.json', 'wb'))
|
168 |
+
'''
|