From defe6054b314e131254752e26db83e0c2ef460c4 Mon Sep 17 00:00:00 2001 From: Timothy Carambat Date: Wed, 23 Aug 2023 19:15:07 -0700 Subject: [PATCH] Full developer api (#221) * Autodocument Swagger API with JSDocs on /v1/ endpoints for API access implement single-player API keys WIP Admin API Keys * Create new api keys as both single and multi-user * Add boot and telem * Complete Admin API * Complete endpoints dark mode swagger * update docs * undo debug * update docs and readme --- README.md | 1 + frontend/public/anything-llm-dark.png | Bin 0 -> 8413 bytes frontend/public/anything-llm-light.png | Bin 0 -> 6324 bytes frontend/src/App.jsx | 5 + .../src/components/AdminSidebar/index.jsx | 11 + .../Modals/Settings/ApiKey/index.jsx | 198 ++ .../src/components/Modals/Settings/index.jsx | 2 + .../Sidebar/SettingsOverlay/index.jsx | 7 + frontend/src/models/admin.js | 45 + frontend/src/models/system.js | 43 + .../pages/Admin/ApiKeys/ApiKeyRow/index.jsx | 69 + .../Admin/ApiKeys/NewApiKeyModal/index.jsx | 118 ++ frontend/src/pages/Admin/ApiKeys/index.jsx | 109 + frontend/src/utils/paths.js | 6 + server/endpoints/admin.js | 69 +- server/endpoints/api/admin/index.js | 642 ++++++ server/endpoints/api/auth/index.js | 33 + server/endpoints/api/document/index.js | 194 ++ server/endpoints/api/index.js | 21 + server/endpoints/api/system/index.js | 153 ++ server/endpoints/api/workspace/index.js | 430 ++++ server/endpoints/system.js | 112 +- server/index.js | 2 + server/models/apiKeys.js | 133 ++ server/models/systemSettings.js | 57 + server/nodemon.json | 6 + server/package.json | 9 +- server/swagger/dark-swagger.css | 1722 ++++++++++++++++ server/swagger/index.css | 3 + server/swagger/index.js | 28 + server/swagger/init.js | 37 + server/swagger/openapi.json | 1767 +++++++++++++++++ server/swagger/utils.js | 52 + server/utils/database/index.js | 2 + server/utils/middleware/validApiKey.js | 30 + server/yarn.lock | 39 +- 36 files changed, 6098 insertions(+), 57 deletions(-) create mode 100644 frontend/public/anything-llm-dark.png create mode 100644 frontend/public/anything-llm-light.png create mode 100644 frontend/src/components/Modals/Settings/ApiKey/index.jsx create mode 100644 frontend/src/pages/Admin/ApiKeys/ApiKeyRow/index.jsx create mode 100644 frontend/src/pages/Admin/ApiKeys/NewApiKeyModal/index.jsx create mode 100644 frontend/src/pages/Admin/ApiKeys/index.jsx create mode 100644 server/endpoints/api/admin/index.js create mode 100644 server/endpoints/api/auth/index.js create mode 100644 server/endpoints/api/document/index.js create mode 100644 server/endpoints/api/index.js create mode 100644 server/endpoints/api/system/index.js create mode 100644 server/endpoints/api/workspace/index.js create mode 100644 server/models/apiKeys.js create mode 100644 server/nodemon.json create mode 100644 server/swagger/dark-swagger.css create mode 100644 server/swagger/index.css create mode 100644 server/swagger/index.js create mode 100644 server/swagger/init.js create mode 100644 server/swagger/openapi.json create mode 100644 server/swagger/utils.js create mode 100644 server/utils/middleware/validApiKey.js diff --git a/README.md b/README.md index cf49a77e..f427ef50 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,7 @@ Some cool features of AnythingLLM - 100% Cloud deployment ready. - "Bring your own LLM" model. _still in progress - openai support only currently_ - Extremely efficient cost-saving measures for managing very large documents. You'll never pay to embed a massive document or transcript more than once. 90% more cost effective than other document chatbot solutions. +- Full Developer API for custom integrations! ### Technical Overview This monorepo consists of three main sections: diff --git a/frontend/public/anything-llm-dark.png b/frontend/public/anything-llm-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..a294843869eface3065ca61c413528b3bfca668d GIT binary patch literal 8413 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 GU;YOq98zci literal 0 HcmV?d00001 diff --git a/frontend/public/anything-llm-light.png b/frontend/public/anything-llm-light.png new file mode 100644 index 0000000000000000000000000000000000000000..341d21b6cea9a1b7b8ed431920931c55f4d1c0c2 GIT binary patch literal 6324 zcmcIoga@p-6~FjRyb#2$hxObN~QMKlHa14mSEpa9HJqe&M<) z8F~N!_@w`C3_xZ!CAtyALr3uqpn8mU5B-B>2T_Lr0N)evQ5HY|fKpjm4)WFq<0!{8 zm8{>r-|E9sJ@z*jPiP|^xzhHBm zPz$9{gmbOpP}{_QuvWWcuko z;SvLv)ng(RTc3Mg>*@7)FrNB~(+R>8WJ>dkbRRdkO8+&(n0?p{(yT=!6-(v~LEu?3 ze>YEK*US( zrm}??>wUsGQ<=B<`qStqB>iaj-9N4@(6^}R9+F}QXKU4H)Fe3uq?G(L*C znsm{BA>Up7@|{& z#Yxng9u*BY|7@U=$?76l7=X$|3x-IniD1kX-m5)fT52oSQ~Z(d?dC?z?GqI?A_X+E zNI2SOd&o@SAc^y@RXW&tpf>_W5*!sx0H;!2Mr#5B^rT48N^GCCCf>K^A)&hCV6{eN zk3%D{-=y1z#NZIwx)OfFJFC?@tNCQ?ct>u6znoAaT;~_PDxpnToTPAQA_>uCF(Bl9 zx9#*!5P|rKz;pdD2_c4#f}Q|*NhU(u*@>Le+BDVE@OMu<)2*64S$nW8oRf5A2$b-7 zDqoY8G%5K509xIc^B((Y!y&}`j4P(DF!~K38$BwIiim@Kb3TTZ|K?9Y$Git7lrbp2 z91ARmzytsWK8pvzk(_@+>@O&0K8x$tz;bJg%_(Me`nH=$3VOcr`LJSgENCe2HGkYS zMh`J#%6F(~ru=Q=WNSX#gUBJ$_H0=6d!`#r7btwab_l_MiB-+^gMw)LA6Qfec|blx z7Z8^=vrc5wj%DTCZL5uNJFF?2ZJgaRoGboxe~u@6A1$V|$Int+pO&2ZB6yXB_MEMs z0mptVs6%fCnF0XFb}k8B&9|yXITY*ceV7h|U`a-d7CkU^u(c~Fa^onWIT7$?=mPn3 z5PIGQIyBVsy^$Em(|B54&d5RQr?~+D@V?)BlR8zU8YZEENCl@12}PVvI(28o=tujd z2#ItH(`)jo)}2v0NWC=}X?#ZLNs`RR)KgZ%2mqvGr-{ESKA(5G*=jGQr+ho%baP;; zD6jJ6TRKIR_D{}W235>?OYpM$Ljn2TkJ@YgMKA0Ixz!@iYbrFiIZIHUUX$LPx}RzC z0_l5=3aGyZ$ogUExTTH_Qw^ge`65`;qwhKRtnlpmW8nj#=wmd$T-fiQGjGX~?wJV_ z7%NOE&he-@_#;6&`xy73$rmj*NkU5n4zL>b2H6x{@wJ?f^yT+|gNl{pvidJ9T~jN& zfRbn{J~E2|Za26DYc0rV zD%Wn!`SxMl7@Aw!%LTx>;1EAx|oPp)JLOQeK*UT*}2{{{cwHy z{=W^~5m#_QF5!5KvSk5Ke>e}@7;*IYxUY}sjpTnc zcGWgZKv18=?2qIfaoy|#%Z>Ez-fQ3O8PBYsLf^bfvWa*OrCG+6jy!LSB?kG4kAtBI4BD5+4R*Hj|G|hgfDtV&=ktZ7e0Nni0Tz0Z>5-#+UGZ zix|!{KVf{5bCItzKPkVlV-!(b4jkW@lE8S>24oD_EAm_&1LOoM?tN5t?h@eS>SoG& zhK^y9Rx~UzTB#TIK*cMPX-7Mc()|Ch^d2{JHXFI=zqr#u_8bLH!C#KwRG>g4UE&cXChZh{< zZ*(-Zo8kE+YL*Nx_vtwF1uBT?WHxgLeRImhX7N;nM1^I?uS?C8w6rAm>VgSftQd-C z9AWS4nePoo+%l6D{Tpui%HJ+9h%aiG7Li?Amo&Yk=_fuftWDR2(mb{w{ngRZy3T$D zmP}RVen(>nrlPnw&*r$UIu*#*P@H0!%<58%KXGY>5MRoK%(_aGW!4BegG-nOt_4{KD z3lxdabrP40KLNb#O7K8^`r(kxHvXrk-#EkcY~Cr|xoYXiu6!#+8`m#x4S#s;yTYkF z_+Pql2Pd>28;Izs`B79Y!j>#1#j0=&)~>T#^=h8s)m`fz+z`p=$SqhQv?_vspG9O5 zh33(Tf)oR4_yQ#76~g3To-!n@9;I(j0J2dy!9kIA}z~IsXzmnKcPH)2p%@m*)0pcL}Dg(-WNB!ZJ zEZ4=fi&L5J-1KbMrTJ&&O3yUGy}4qkLf^ESN58Z^;Tz=aH|@MgFM9des!8 z$^&lomWjx~);rc4xpf*4A^M?fBZpVR{wBma&KN+#;PyOrEG2u6!CV!V7O2^mL!e{^ zWmUz49UpSyBWE#q+33KqCJ(co2fYW=n-4MeA2ZC76-@WoR}QQabvcmgB<;#}R1U*Z z_5WSkRzA>-Xqpk^aU=7rEImekw`!w(nnqs>BDpf~cO0#;TW@-eI?uG`-W@Eq_8i+9 z#EqZeCMI+&s0{kgK)Ys;BG6bTSdI{Nu9ljzARH}bx;-=PylN&e+dK6wyb;0Ah$w6` z>}v?c@lWk6`16w?hx=!qFBkP+`^}qj#|p?BxrGgQUFl_Q-|0!YmHYhenVc@=zCIbP zD?}Vzno3>qb5WY=1;mvdpbFm2o3n{1`+C&zG zqp~D**Du*&+?N#-`oWMa)mpXSa}JN-E@9BMb9bQT-kQf%5<*xNqM1#cW_=A2lL&#D zamrCDeSRq_fB#}Wfyb5eW8c^Ene3YQyIHNIAilSWWdRz()kK!H_WpcI0z-ae~(%0(0XRgw%c+u8qA=%koQ%St5ou$ z*nun>Z(p$@tq}1xnIcA}P01u7!%-~yvGhvKB6||AVqRNY)w*r|jz4I((;}xzLDys= zq$jer-{_PqCRF2m>xfw~&TM46L-Sc8S&JY^Y5M|X-aWgwQs5;A>zF2GC_nw-bO1Ht zD4Z3~qqvy2{Vh012S=FvM}OVDK|{GOsBktE2Kah7KOH(rAC^_x1xH%ddKCzIzYuQGJFX_B*`Lv4g&cz zJd$2db#AWX?lG|c_kAV{orKO1 zKmgXMHbDLL`#bD(E=U-w_9oj!lJ&;2s+@h^z_~>M0$D@GPerIFe14dT_yVg~aADgSmhh=3)JY((pP!|AXHnq=3i8inybVH8k_T-mv~RW)>o`E*twt zO4fxNfP{mv=X2I{9a;piQrICun*t;|_`Q8;pd~2FmGFWwA zw{d=(@(-G$*~BKjr0xQxzN1zh_l}D)0Tq+JTqL_4RSS=Toj>z2hkU4JO(oxB>*?)# zG#)v_=?1hjTltn$j(Nz}@#XW)c^7bC30RC%IE3DA2~x>Te0g@5E=B;i&%clK1^6mo zkg=)^F$D3{(|gBwUK+wV1k{_Bz$+Qtj6`~IG5PY5 zl!bW2n%3go$P3JTmcm)9u6W%h(V zzubJXLF*O1&Z~Rc%W8Rb7v)@w>kVzbd`qbtFLp3Srz=a7+~v{})%Bz00<8{Pwt?R1 z7gHN$!t*QYH}uAQl^pGWW(ta{h4bAQugc@_RjhV}?mts*26O@1+W2zDXESa%_+;Z{ z)w47ii;cEp+sov8F#hJp;~22(lsvIQNu{@c-wA0z-@aIFG2SX)~U*lE>rP zL&>C!Y15M)+KJ<23sETO?T}yEwh!W|o`9x-l(&J*2AHg7Kw*8DD*T~uo1fw)lf&4j z>p~IlKLWHhS@fh33@IeEl#FqJ@&pR?D-K|O#Rf=8n0bll>+!H_RKNTC(YGFGM2F*y8A7%B)uO7t3 zuMt!o3{|PAprnLeu&M4iu|%{u!FG|n__T*4J@PSbo0I^g3Sml7OglAcE4}&1qMjp@XUOwi2WZQLCz#tT1tK zC&k&l;KohsnWam4I*#55st%Eld45rChN92kU#B{RX{US{K6_g_d}7$9uHta{QR;=7 znuZOjgPg;>1U??wu=gg+8YUL3{5)c zU!F5qDk%1KHNA{on)LOI zF3R(TG5mv$v#sv|;(!qtr|)I)1&^qzB+vzSCky$cBz&5+ZQw}u3v!)%+~<^?P9h^U3cjd$duIWbjMJ&Q9k0ctMI>6?B>sVzEKeyobfd$Yu%>KY+*TrmK3GIm^+o)uTQt=3)j&bzNY5kf@c z1d;DGt+cv}?5#-O5np0cDSEA4p@brkGbpq9!O5k>O`2cP)FC7D~5)(UPXqKiEt@Ke&+?mZ5i zkk6f%xyetU|J}JC4l93CLiV-rBqPRgG0>nuCeqmq_aw0w0RA$j-?MKPa^j>O{G)-Y z8`Rf1@d>cFyEH&~jp%x-t32n`wmW_-=1WG&alWVDhy74s0v9eBUw z1QztAU`qJm`>2G5$k0%ePI`7+^fZ1D!b8J~UDL+K!g&7i1|umdteb;gqy&eJd^NSc;&O|GiuC19x(+Zz-GsLn&Sd;pUCzEawduOkLH!sc zi?`#1`uO3NwdQv!&!-2PeMw)m?;%m^)tS|+G281osKAp$)OP;plNS)ME25d$FzbnP zU7*H4zwokG6df2M8-PXKKnvIPa{xXIFD{%J&`Bmr=hrF#s2r#UapL)lJi}G|hUksw zLdztrPdQu~kbcaDnm07(FK*-)B~%AL%%?45b;^Y(JPUEqc4EF;2%!tnARb+vO3PzE z^#A>o)~Ac4F?gpY_zl(v~Epgm<<=S!vNe2{-#d64=Uh z)pX3iHIGB6J6akr8S)O|cv$`g*p!)+h?N82#fZspa%SRmV;Kfdxbf=Dmg%+z@OJ_0 z572or`B&L$F?bgmXvjcITZtQzvEF^mSK0Nt1T~np+#t@xkF3;#x0RgUqcElQctMQ2 z7>OLrH{@}_-x7~8LRKOH2F|F9r#PPGV<>6taisUQK)}C}IzU-oL$3ObIqZJ`K|SVE literal 0 HcmV?d00001 diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index df74f73e..b6cfc7eb 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -14,6 +14,7 @@ const AdminWorkspaces = lazy(() => import("./pages/Admin/Workspaces")); const AdminChats = lazy(() => import("./pages/Admin/Chats")); const AdminSystem = lazy(() => import("./pages/Admin/System")); const AdminAppearance = lazy(() => import("./pages/Admin/Appearance")); +const AdminApiKeys = lazy(() => import("./pages/Admin/ApiKeys")); export default function App() { return ( @@ -52,6 +53,10 @@ export default function App() { path="/admin/appearance" element={} /> + } + /> diff --git a/frontend/src/components/AdminSidebar/index.jsx b/frontend/src/components/AdminSidebar/index.jsx index b185d4f9..a583cb32 100644 --- a/frontend/src/components/AdminSidebar/index.jsx +++ b/frontend/src/components/AdminSidebar/index.jsx @@ -3,6 +3,7 @@ import { BookOpen, Eye, GitHub, + Key, Mail, Menu, MessageSquare, @@ -82,6 +83,11 @@ export default function AdminSidebar() { btnText="Appearance" icon={} /> +