From e65b05b4519ed6bd4191d8f31ac260493bcc3086 Mon Sep 17 00:00:00 2001 From: andrei-mihnea-cerbu Date: Fri, 12 Jan 2024 22:19:19 +0200 Subject: [PATCH] api done --- .../__pycache__/__init__.cpython-310.pyc | Bin 167 -> 0 bytes .../postgres_database.cpython-310.pyc | Bin 1210 -> 0 bytes .../__pycache__/user_queries.cpython-310.pyc | Bin 1937 -> 0 bytes .../api/v1/database/postgres_database.py | 38 -------- messenger_app/api/v1/database/user_queries.py | 81 ------------------ .../__pycache__/__init__.cpython-310.pyc | Bin 171 -> 0 bytes .../__pycache__/security.cpython-310.pyc | Bin 540 -> 0 bytes messenger_app/api/v1/dependencies/security.py | 11 --- messenger_app/api/v1/endpoints/__init__.py | 3 + .../__pycache__/__init__.cpython-310.pyc | Bin 168 -> 225 bytes .../__pycache__/messages.cpython-310.pyc | Bin 460 -> 0 bytes .../__pycache__/users.cpython-310.pyc | Bin 1584 -> 0 bytes .../{database => endpoints/auth}/__init__.py | 0 messenger_app/api/v1/endpoints/auth/login.py | 1 + .../__init__.py => endpoints/auth/signup.py} | 0 messenger_app/api/v1/endpoints/messages.py | 9 -- .../api/v1/endpoints/messages/__init__.py | 19 ++++ .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 731 bytes .../get_conversation.cpython-310.pyc | Bin 0 -> 589 bytes .../messages/__pycache__/send.cpython-310.pyc | Bin 0 -> 758 bytes .../v1/endpoints/messages/get_conversation.py | 9 ++ .../api/v1/endpoints/messages/send.py | 17 ++++ .../v1/{models => endpoints/user}/__init__.py | 0 .../auth.py => endpoints/user/user.py} | 0 messenger_app/api/v1/endpoints/users.py | 45 ---------- .../api/v1/endpoints/users/__init__.py | 26 ++++++ .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 884 bytes .../users/__pycache__/create.cpython-310.pyc | Bin 0 -> 775 bytes .../users/__pycache__/delete.cpython-310.pyc | Bin 0 -> 538 bytes .../users/__pycache__/update.cpython-310.pyc | Bin 0 -> 685 bytes .../api/v1/endpoints/users/create.py | 20 +++++ .../api/v1/endpoints/users/delete.py | 10 +++ .../api/v1/endpoints/users/update.py | 11 +++ .../__pycache__/__init__.cpython-310.pyc | Bin 165 -> 0 bytes .../app/__pycache__/main.cpython-310.pyc | Bin 320 -> 436 bytes messenger_app/app/main.py | 7 +- messenger_app/app/models/__init__.py | 2 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 234 bytes .../__pycache__/message.cpython-310.pyc | Bin 508 -> 507 bytes .../models/__pycache__/user.cpython-310.pyc | Bin 456 -> 453 bytes messenger_app/app/models/login.py | 6 ++ .../{api/v1 => app}/models/message.py | 6 +- messenger_app/{api/v1 => app}/models/user.py | 0 messenger_app/database/__init__.py | 2 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 282 bytes .../database/mongodb_database/__init__.py | 4 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 309 bytes .../__pycache__/connection.cpython-310.pyc | Bin 0 -> 1398 bytes .../database/mongodb_database/connection.py | 36 ++++++++ .../database/postgresql_database/__init__.py | 4 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 323 bytes .../__pycache__/connection.cpython-310.pyc | Bin 0 -> 1817 bytes .../postgresql_database/connection.py | 54 ++++++++++++ messenger_app/database/queries/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 168 bytes .../__pycache__/messages.cpython-310.pyc | Bin 0 -> 1745 bytes .../queries/__pycache__/user.cpython-310.pyc | Bin 0 -> 1538 bytes messenger_app/database/queries/messages.py | 62 ++++++++++++++ messenger_app/database/queries/user.py | 56 ++++++++++++ 59 files changed, 349 insertions(+), 190 deletions(-) delete mode 100644 messenger_app/api/v1/database/__pycache__/__init__.cpython-310.pyc delete mode 100644 messenger_app/api/v1/database/__pycache__/postgres_database.cpython-310.pyc delete mode 100644 messenger_app/api/v1/database/__pycache__/user_queries.cpython-310.pyc delete mode 100644 messenger_app/api/v1/database/postgres_database.py delete mode 100644 messenger_app/api/v1/database/user_queries.py delete mode 100644 messenger_app/api/v1/dependencies/__pycache__/__init__.cpython-310.pyc delete mode 100644 messenger_app/api/v1/dependencies/__pycache__/security.cpython-310.pyc delete mode 100644 messenger_app/api/v1/dependencies/security.py delete mode 100644 messenger_app/api/v1/endpoints/__pycache__/messages.cpython-310.pyc delete mode 100644 messenger_app/api/v1/endpoints/__pycache__/users.cpython-310.pyc rename messenger_app/api/v1/{database => endpoints/auth}/__init__.py (100%) create mode 100644 messenger_app/api/v1/endpoints/auth/login.py rename messenger_app/api/v1/{dependencies/__init__.py => endpoints/auth/signup.py} (100%) delete mode 100644 messenger_app/api/v1/endpoints/messages.py create mode 100644 messenger_app/api/v1/endpoints/messages/__init__.py create mode 100644 messenger_app/api/v1/endpoints/messages/__pycache__/__init__.cpython-310.pyc create mode 100644 messenger_app/api/v1/endpoints/messages/__pycache__/get_conversation.cpython-310.pyc create mode 100644 messenger_app/api/v1/endpoints/messages/__pycache__/send.cpython-310.pyc create mode 100644 messenger_app/api/v1/endpoints/messages/get_conversation.py create mode 100644 messenger_app/api/v1/endpoints/messages/send.py rename messenger_app/api/v1/{models => endpoints/user}/__init__.py (100%) rename messenger_app/api/v1/{dependencies/auth.py => endpoints/user/user.py} (100%) delete mode 100644 messenger_app/api/v1/endpoints/users.py create mode 100644 messenger_app/api/v1/endpoints/users/__init__.py create mode 100644 messenger_app/api/v1/endpoints/users/__pycache__/__init__.cpython-310.pyc create mode 100644 messenger_app/api/v1/endpoints/users/__pycache__/create.cpython-310.pyc create mode 100644 messenger_app/api/v1/endpoints/users/__pycache__/delete.cpython-310.pyc create mode 100644 messenger_app/api/v1/endpoints/users/__pycache__/update.cpython-310.pyc create mode 100644 messenger_app/api/v1/endpoints/users/create.py create mode 100644 messenger_app/api/v1/endpoints/users/delete.py create mode 100644 messenger_app/api/v1/endpoints/users/update.py delete mode 100644 messenger_app/api/v1/models/__pycache__/__init__.cpython-310.pyc create mode 100644 messenger_app/app/models/__init__.py create mode 100644 messenger_app/app/models/__pycache__/__init__.cpython-310.pyc rename messenger_app/{api/v1 => app}/models/__pycache__/message.cpython-310.pyc (56%) rename messenger_app/{api/v1 => app}/models/__pycache__/user.cpython-310.pyc (82%) create mode 100644 messenger_app/app/models/login.py rename messenger_app/{api/v1 => app}/models/message.py (66%) rename messenger_app/{api/v1 => app}/models/user.py (100%) create mode 100644 messenger_app/database/__init__.py create mode 100644 messenger_app/database/__pycache__/__init__.cpython-310.pyc create mode 100644 messenger_app/database/mongodb_database/__init__.py create mode 100644 messenger_app/database/mongodb_database/__pycache__/__init__.cpython-310.pyc create mode 100644 messenger_app/database/mongodb_database/__pycache__/connection.cpython-310.pyc create mode 100644 messenger_app/database/mongodb_database/connection.py create mode 100644 messenger_app/database/postgresql_database/__init__.py create mode 100644 messenger_app/database/postgresql_database/__pycache__/__init__.cpython-310.pyc create mode 100644 messenger_app/database/postgresql_database/__pycache__/connection.cpython-310.pyc create mode 100644 messenger_app/database/postgresql_database/connection.py create mode 100644 messenger_app/database/queries/__init__.py create mode 100644 messenger_app/database/queries/__pycache__/__init__.cpython-310.pyc create mode 100644 messenger_app/database/queries/__pycache__/messages.cpython-310.pyc create mode 100644 messenger_app/database/queries/__pycache__/user.cpython-310.pyc create mode 100644 messenger_app/database/queries/messages.py create mode 100644 messenger_app/database/queries/user.py diff --git a/messenger_app/api/v1/database/__pycache__/__init__.cpython-310.pyc b/messenger_app/api/v1/database/__pycache__/__init__.cpython-310.pyc deleted file mode 100644 index f658ddb54589007d5bc5857312a7d6a6a60a689a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 167 zcmd1j<>g`kf}JgMQbF`%5P=LBfgA@QE@lA|DGb33nv8xc8Hzx{2;!HQenx(7s(xZ# zN>OU2zDs^`X>Mv>NwI!zYH@LDUV3T~f)$@wP@tb!kf~p0sGpKpl9-fOoT?umpP83g c5+AQuPdnDE3heQ9=!BQj6L&b!ycxb!hqo)d-!Zb2NK`YX;5HJa|lstEg1?1$$9NrQ1vh z7923HvTi^*Yt=o*8y#gQmP-4f=lac1NM$~Ju)bEZlua9f+h)q_2-xOCt`OajQ)MPu zQOKpIPoE3|imqr2mZ*T}&q;KMDQO`|zT=O0hz4j6RgsCnZ}jeAG{hM7^Ag@Vz+cc; zat!t!+J|a~_y|+TO|&lVqLNYRmv%T0`Qzg2z-{=fD8r%`1_AS=R%MeFsVm)vD_G_S zf(o2S^t>=SSW~HSo|@m@e6{&(v$|8?dRf_h@myK)k;;mAE086kGULov7%0qm7V3z_ zd9~aO+pL`6Ro)K0PMZZ%l&8pEYIQe?%5KyuzgsO&UQ~_%+XK!-ed1Y(dTPPr%$2Nu zd8xio6hIJMz&5NrOy>i+;5Wdz>zN=YBL&J7@o!-C*9YhfjnJpNLvvuB0jdKsA{Y$} zz63TIp`kUf_7DMFO_;}q#=8oY z_7w*0BYVssXfcDN(qI0MLH3?`9SLLteQ!IA_cEoFvb_!$Ay=t!R5@>$^qQ{kLnv&w zTaxFXUao=S3m{4#YZSRa=F_U{FaX2)Bziy@A#5m)1E1-{JM_i#<$et%^GL1 z1cKlU&SDcgnBc{~8T;OOAvI;=HY9i$#AIk){{nIQ>+J)$C!qr)i7D32od5zqCP1;c zmGmxjTG8`E!RQL~pB1Y~O*pRU>T3&e#!SmB!)3w&p`Qv5zTkJjfGc)ORsz#J*m3`G n{p>hAb83u6421Kf9ny}^p6X(Rb~%U`1nSq*{^O)G>1_TVSot6e diff --git a/messenger_app/api/v1/database/__pycache__/user_queries.cpython-310.pyc b/messenger_app/api/v1/database/__pycache__/user_queries.cpython-310.pyc deleted file mode 100644 index 39b04cccd8cc76a93cf1c017749da33491f654c6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1937 zcma)-OK;mo5XYBKQHrG6j^Q=|+As$LR$)lUrH3?qq_Kh;NR`5p8^936fE3wX zGOh{g_A8_s6TjlFP|ci4~2OX{#q~q6yuej(Z&^%uT2P-r zz5E_bOwP$%$rQew-lxi3&B&25*J2pS)J(%m{;bdSOy_n6SG_~#MrOPqv6?C8ibBR@ z(WcO=#!ums;o8P1eblm-%6Rx}_+(;#Y(L$5{*9do#)bXj>*3ze_Ne`ty(vDeEuUN{ zxpl;1_r&pij^DwNYtPIZxOeK&ytPEaCYnl_panl2gyRG1ZL<*Un|Cbw?jf;BYjU|bDMRhHEyzJgJyE-lme zy>uParDp_nb)?M=P?(nKnQ;!GAT^|+o=OeLcBvtCl%CWm?2g96y@|a$nmjKRw1wzr zPQbS9$PwZ+ZHjG>8rEK2ZcHHp4&=AtbFNdn#;RKe zr&Izx+=3kfAyzVI>0Je!|BAm4gD$G1D(IyuEX4#m5*&uzR{9};Gm3D8;MC_PpaXE3 ziRfaLLdgC~sP?;r1}FjR70R+*qSQxeS_88G?at%Lu%K9*7!N0M6roC4Ey$MLh2m-( z|09@RclNa8NL&{p?$d#ZSK5wrC06F69)q$^LgjkdCezWSSg1jDsJ#fx3} zY6P9D6uOz-eKUpL=p~szrQo$9nJ&Eau*P%;k|ucR|D{a+0o(}KQs%Qa*z!9t+0!M+ zcWJpepd$1XHr5E4T1n^?zXx-pUNgTBX|n(FLBC3q{U{XiF(lz>HL~!mbg4{&GKg`kf}@3VQbF`%5P=LBfgA@QE@lA|DGb33nv8xc8Hzx{2;!HYenx(7s(xZ# zN>OU2zDs^`X>Mv>NwI!zYH@LDUV3T~f)$@wP@tb!kf~p0sGpKrkeZj0nwOlJTC5)* gpP83g5+AQuPLP9%>@QYB%PBnkxY8;WK5+mTbP-o zBN7GQI6;O2Q5y5GYN0=%n*oNBZ0MG}QOs;jHlCzgx~5z9#@1{^c5L|CT9nhvo5;7p zv(S|)ZF>f}iRYyalGr3_Wdq1XAtCZ?sA6MQg_hQ@CwguIh# uw*;L|tL7!{+Bl>>)#sT00P7dk2S)%kRE-keW`$hL;m-Zso(KuOPVftb+j=i$apO=@50SNMs&Pz20(vLwLWWWUEH~?|67?4O|NMX!j$YqRTWMoKXY-WgJ zN?{6S&}4oIlw;6jyv6Al;2D%(T9R7ir^$SaJuR`gB(Wf~2xP`Bwj!{^N`@jS5Z=vhleV-4K_8-*EWJxn@FHRnz2#CucUmh+cG*b^iU*}$eFI;h&(XKY z)swH_$=S482WI$Yc7DE@HT`~~@^}6!gamUZiks z0+V4>NAna*YU2V5)F*`E)hKQj!gyclgntWNbB|hDgJn~HAihJ9Pivo2ah1W?Z;k%z MdaTDo-V?|C2O4s43IG5A diff --git a/messenger_app/api/v1/endpoints/__pycache__/users.cpython-310.pyc b/messenger_app/api/v1/endpoints/__pycache__/users.cpython-310.pyc deleted file mode 100644 index b91d312d4dcd09f18d8df26a06234bbe4e7f87d9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1584 zcmZWp&5qne5O%jcw#Va{ok=!QA_6Q2K+a)Cxko5SAce~+f^hN0^16Gnj{HY=JIO{9 zDKH$#jSFan;F#y&%nS6D)4oE41XblEJIi|1HC5H+cGdS)bvvC#4m>~odMf`KInLi` z>^>eCcVX$@KnO>$%Bfk(YMye2Hm}^;OFh!vYE=8FUk7PGwg+~YhV?id*HIdgZ&Xd{ zIE|Sj+15#?a{BvB_$WD8@f}TbAyDe@_00{1XwAe*yk0#H{-h&7CzkFKA&XjGFFzbD*rGl8nLus-e^z7&)lXYHJ zcDCy(MdI37p=5645GRi8tnb7HTgXbD@5Axa<6IwSU9R<$R*7f+3O}K(hkpgb{N6kW zECBBO2}`d*e9w%taUQWPd(JjY%?uYzaN)k>KQQCMj%P+7{Vl^N;k|U3^X?74;bL^d z0qK(rNQO5YF+TO4yCT}SVsgp>r1-G>1@d@y6>&JoD=1K$9LT4oHu@E}6K!(S>#S&n zw7!rAfB_&v%)iNNX~Va**%6_pu&6T<95ok2;#pn_wFj!2qga5jk?xB^YQ63&z~3J} zq$U_2D1?H-6ds@g6!bo}CmoV_6l;AYbzd1958MbM$1ZlQOq7Lr<*4`I-PiY4$89ZF zc_Wl8S6{S6U(3emRSl`g=Al&QT9$X+D(}kG}TNM^^90;T63^&d#E^u!-0(eYsgAr$C%I1?J=tFXeH|{wMnQjJ#`HQ z@e!hiEdHMqu08;-4ckgkorL)yZsNvdXJXKyXCM%>5HO2y{i{9!m--0AC6I7P2&7w} z3?L2TK@ja3wlgAp<7^q;F#v~ms6NC)4^R*W?obgGGX`(M>5J4-mvY{j>W?8-BiZ~# zNIAz$eG2Aba?J+o9GbW*74k_q*(+c!AKzZqFg}%DBD@NVus7dq!1a+IoYBO}5+x3P}#R%DT|W pl=n`pI30>e3hzL^eI-A`F{ZAbJ29KHec;FEp*v^c0#>-s{sV74gKPi* diff --git a/messenger_app/api/v1/database/__init__.py b/messenger_app/api/v1/endpoints/auth/__init__.py similarity index 100% rename from messenger_app/api/v1/database/__init__.py rename to messenger_app/api/v1/endpoints/auth/__init__.py diff --git a/messenger_app/api/v1/endpoints/auth/login.py b/messenger_app/api/v1/endpoints/auth/login.py new file mode 100644 index 0000000..c249d51 --- /dev/null +++ b/messenger_app/api/v1/endpoints/auth/login.py @@ -0,0 +1 @@ +from app.models.login import Login \ No newline at end of file diff --git a/messenger_app/api/v1/dependencies/__init__.py b/messenger_app/api/v1/endpoints/auth/signup.py similarity index 100% rename from messenger_app/api/v1/dependencies/__init__.py rename to messenger_app/api/v1/endpoints/auth/signup.py diff --git a/messenger_app/api/v1/endpoints/messages.py b/messenger_app/api/v1/endpoints/messages.py deleted file mode 100644 index eec4f71..0000000 --- a/messenger_app/api/v1/endpoints/messages.py +++ /dev/null @@ -1,9 +0,0 @@ -from fastapi import APIRouter -from api.v1.models.message import Message -router = APIRouter() - - -@router.post("/messages/", response_model=Message) -async def create_message(message: Message): - # You would typically save the message to the database here - return message diff --git a/messenger_app/api/v1/endpoints/messages/__init__.py b/messenger_app/api/v1/endpoints/messages/__init__.py new file mode 100644 index 0000000..f0a88c7 --- /dev/null +++ b/messenger_app/api/v1/endpoints/messages/__init__.py @@ -0,0 +1,19 @@ +from fastapi import APIRouter +from .send import send +from .get_conversation import get_conversation +from app.models import Message + +router = APIRouter() + + +@router.post("/send") +async def send_router(message: Message): + return await send(message) + + +@router.get("/get_conversation/{conversation_url}") +async def get_conversation_router(conversation_url: str): + return await get_conversation(conversation_url) + + +__all__ = ["router"] diff --git a/messenger_app/api/v1/endpoints/messages/__pycache__/__init__.cpython-310.pyc b/messenger_app/api/v1/endpoints/messages/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..88d817c5e77796204430917b0e9f69d7fd08c7e9 GIT binary patch literal 731 zcmZ`$O>fjN5Vf7p%_iGWA@K*e?4=fWgh1jz53LaGDHkhRyGtY|j_hnD3Y9?1->5{7 zz4H(F7rt`pi9>HabtX&2Y9$=`dFE;2d2eirA|tT=TwSZ5l#t(;Y_AZK*RWj=Ac>@! zw6vm>NG1c#T2`?!4t3B5RRA%Okq+CaiYQTZO{!SMKN1;VQ<Q z2K-cIz~{0U`Kg>OX_d>p6EZJvp(~kFKY8>1@PkY*_mR3}Huxq7KCB92u)X*c--|9xB-GuXdi-<1I0=s>=ZH9Z6m@5l)>IksqjPVEGa z8)9=f?oatg(<)wf(yE5PHH%fNy1{Ymp}M8A{~}TMJ+J$QpTFRsqc_cCA&7Hah^A`> zArAUaeu_ec9W7$FJM7H9&X}D+aPge)+T@?NO^cP)m%iMk{%hFctJ^6;3;-5!0;9nV z6p;F7yG{QJL`ilJ;R%+-8`;P6!Y6078^E!}$=V1Z!IBInanKs6w6iI)`^bj9al>fP w2hhp~kZrC^gs8O^VoMPY-;T1P)*@!=$Y zdw4uPNV(~Rt$thaEi+-DzfZC=U127aG+1N@de&5^oXsk<7S#gHW0#A%&O}{gms=Ss zS?l88L9sxaEzmug(5Sxl!{>`Zhz-R2QxAHu3Ne^I!ExI4-MJu(ba8dJK7MT-!k;H0A(gD7lYpbW zAAm$d$?xD_EF~2^6&16-AhOboXJ*Ia_ujY}kB5xTkI!G>RxtL{CHu#tD){6tLlw?h68)n0S;Fo3bg?))xy+$8 zMN?BDd<|O5H6+45$PuK0EN|)yKrLN|eWamQS#{TxnI@~6dfljV8}4d3ccXX5;q}SB zlj#|`58SXVd&|khjkxApu2{$MvGKO9=FGqGuEkd1vEoW7?~9l-Gf=+6e=9!nJ`V5V zB$_QYM?1tZAv3Y=@|?h}y0W|?4&g4xfIeRQCTyFBuWAEW%QBt=60!IMu|ev+r;Rk7 zCcX-6puotY+#L6}aW6$tuj73&k^mh!8#qk>ZG@0RK_hYC%A@^Wq;;~y>v7o0{!P|l zi6Py7V|YN1KWFKirh-(~3ZY0}HhEVOGo3ntp#v+NSu|NGsH- z!!>QMtnUJ+fS!;O?+C5=3n t8m8|$zykDiw{qRf(39?G^)&X}efM_sjAnHuJa_+xj>wJJh)?*T_ZRTl&awai literal 0 HcmV?d00001 diff --git a/messenger_app/api/v1/endpoints/messages/get_conversation.py b/messenger_app/api/v1/endpoints/messages/get_conversation.py new file mode 100644 index 0000000..1a76144 --- /dev/null +++ b/messenger_app/api/v1/endpoints/messages/get_conversation.py @@ -0,0 +1,9 @@ +from fastapi import HTTPException, status +from database.queries.messages import find_conversation + + +async def get_conversation(conversation_url: str): + conversation = find_conversation(conversation_url) + if conversation is None: + raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Conversation not found") + return conversation diff --git a/messenger_app/api/v1/endpoints/messages/send.py b/messenger_app/api/v1/endpoints/messages/send.py new file mode 100644 index 0000000..beea570 --- /dev/null +++ b/messenger_app/api/v1/endpoints/messages/send.py @@ -0,0 +1,17 @@ +from fastapi import HTTPException +from app.models import Message +from database.queries.messages import create_conversation, send_message_to_mongodb + + +async def send(message: Message): + conversation_url = create_conversation(message.sender, message.receiver) + + if conversation_url is not None: + success = send_message_to_mongodb(conversation_url, message.sender, message.conversation) + + if success: + return {"success": True, "message": "Message sent successfully"} + raise HTTPException(status_code=500, detail="Internal Server Error") + + raise HTTPException(status_code=500, detail="Error creating conversation") + diff --git a/messenger_app/api/v1/models/__init__.py b/messenger_app/api/v1/endpoints/user/__init__.py similarity index 100% rename from messenger_app/api/v1/models/__init__.py rename to messenger_app/api/v1/endpoints/user/__init__.py diff --git a/messenger_app/api/v1/dependencies/auth.py b/messenger_app/api/v1/endpoints/user/user.py similarity index 100% rename from messenger_app/api/v1/dependencies/auth.py rename to messenger_app/api/v1/endpoints/user/user.py diff --git a/messenger_app/api/v1/endpoints/users.py b/messenger_app/api/v1/endpoints/users.py deleted file mode 100644 index f736961..0000000 --- a/messenger_app/api/v1/endpoints/users.py +++ /dev/null @@ -1,45 +0,0 @@ -from fastapi import APIRouter, HTTPException -from api.v1.models.user import User -from api.v1.database.user_queries import get_user_by_email, get_user_by_id -from api.v1.database.user_queries import create_user_db, update_user_db, delete_user_db -from api.v1.dependencies.security import hash_password - -router = APIRouter() - - -@router.post("/users") -async def create_user(user: User): - result = get_user_by_email(user.email) - if result: - raise HTTPException(status_code=409, detail='User already exists') - - create_user_db(username=user.username, password=hash_password(user.password), email=user.email) - created_user = get_user_by_email(user.email) - created_user_dict = { - "id": created_user[0], - "username": created_user[1], - "password": created_user[2], - "email": created_user[3], - } - - return {'status': 'successful', 'user': created_user_dict} - - -@router.put("/users") -async def update_user(new_info: User): - old_info = get_user_by_id(new_info.id) - if old_info is None: - raise HTTPException(status_code=404, detail='User not found') - update_user_db(user_id=new_info.id, new_email=new_info.email, - new_username=new_info.username, new_password=hash_password(new_info.password)) - - -@router.delete("/users") -async def delete_user(user_id: int): - user = get_user_by_id(user_id) - if user is None: - raise HTTPException(status_code=404, detail='User not found') - delete_user_db(user_id) - - - diff --git a/messenger_app/api/v1/endpoints/users/__init__.py b/messenger_app/api/v1/endpoints/users/__init__.py new file mode 100644 index 0000000..2c4a38e --- /dev/null +++ b/messenger_app/api/v1/endpoints/users/__init__.py @@ -0,0 +1,26 @@ +from fastapi import APIRouter +from app.models import User +from .create import create_user +from .update import update_user +from .delete import delete_user + +router = APIRouter() + + +@router.post("/create") +async def create_user_router(user: User): + return await create_user(user) + + +@router.put("/update") +async def update_user_router(user: User): + return await update_user(user) + + +@router.delete("/delete") +async def delete_user_router(user_id: int): + return await delete_user(user_id) + + +# Make the router accessible from outside the package +__all__ = ["router"] diff --git a/messenger_app/api/v1/endpoints/users/__pycache__/__init__.cpython-310.pyc b/messenger_app/api/v1/endpoints/users/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..90bb0c427ab3747f37707a702df395620b52e4d6 GIT binary patch literal 884 zcma)4yN=Z`5ViA8ZgL;lg@Ql0%|>(-2!TYwHY;F7lg5g!y-TFLWG6@<3ee>fpl8ed z4*tR|)z;flF=JmKLPElkCo{(rpP4i1vn(O7^p`8~z#-&22J_`X@EErG42Ba<8`9E} zQuLk1Y2DHV-{oH8wSMUv-*198EJNc5P1MF^Oo^a-QYIq#y5Qjz<&khN93J!Jleed3 z3V6mBzwwl3244am@g?9Zv4Z?H-xz$&^GjN8_|ZAp9^XJ^WJ`7YyGEFHN42YRuM{<902LYmCbglLv% zux4wpN1e~aI#8L69Mg`#0F4z;hgc}9`Ty|6@a2}uW4z^W#@Rd$j3&)6-hmHvU|T-h z<~qEn)Ch`6oQzIDzmv9y3zT$CrWHyCCa|r@$OM)}qHgjoBHqxe(I}_gVH!q%I&FKjR5&_&|ap@G^h4)#){p8Wf$&-iYIkc{5 zYCMq7ESN<2oilJ*hkiC+WKgN1^xL@s8$);D<(=;1ObI1(8h z7hiFLx4SgHK)DpzbB~JDX9a zi`@NSW)~a$d7QpzDo9nW4HW5vChsb!olPsS7V0xF*IuUDHdSqrzP^(}t=p!cLgHuB zb^mF*@S}~VqrvTM1o3XjB_H!WG31emc>n#42WB6W$4Tr5rwa9J3q#cW4gAxzLLo~# zrT&Jr@%vgiHCGmJ5VgIV4}=7SL{CGp6j{+DL;(^NAOTI9m6Mr(rQP*ndl4Xz__c_J3s7N7 z8bn1rhzUp77z>D@@e~i5&^%&E>znSdg!}H^@$upAJ4Kh(7ELz1$`tq> zV2%!_OEC1U$)17{N%}KESxo*xZr3T?bH{GjBfsT099YfFqT|3pK=dpgxD#P72qh`; zzIvrv*S!-WT`jd+9qYOTlG3qGy4q$V4d|PIPO3bKOz7JLMiVF#VHz~~IOuw3W{$wm zL3*YOOl1iMRl1``b%CX`X@S;ad5Y#g%VbrhvQp{AMv5g=T7`q5m`$gx_p2-4nR$gk zXT#TsyEbq01sbM9a6f7J)>xA0N=@|n6_8F2rN#bvjYgsEhq}`Sf_5Jf+2rm-_Dl%n WeS5ReQ0KT6p4v7kEU+cM9Q^{tX@#`_ literal 0 HcmV?d00001 diff --git a/messenger_app/api/v1/endpoints/users/__pycache__/update.cpython-310.pyc b/messenger_app/api/v1/endpoints/users/__pycache__/update.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..61d20566b8dc31cccb0e51811194674c6e676b24 GIT binary patch literal 685 zcmYjPJ#Q2-5VgG@w_NUyC_tZfn_JPM2vGn^bs!O%ZC1XUxnQ)rUTiN(P$KcwMl}2Z zN`40|C6!w${sIk*_t0^c=4oc^8NWBSo=(S%){jqL@H=PhX9#vzM8N|xdyfDZ@R~Ke zbiTsQDcw>c zes0m^!p~08RXzFD@}g4UXMG3K;U)!3pS5^asdlYb#B;j@c`4a9GJ8bujyrbAUh)t8 zieGYIJu~}G00#llwRq266n4pCvV<&!_&N?6h-I=+pQ-zsS>SZI(C+ZD?pq*sd)7(U z+iIl&eG2HLs`J>72ExSlMqq~xW&I?$A>YadH&G|8J<|sAk%@_;7Ya;ZZjulso4RaU zlWorn6U6yU*Dz@R%FF>Jem^N*=mrbffMa--cBy1#rdlqjlzF>LH!_lXf|lsfm@+6JECTNjrYSd+l*ksCVZbCM1KKC Cy}4Wf literal 0 HcmV?d00001 diff --git a/messenger_app/api/v1/endpoints/users/create.py b/messenger_app/api/v1/endpoints/users/create.py new file mode 100644 index 0000000..2de5e38 --- /dev/null +++ b/messenger_app/api/v1/endpoints/users/create.py @@ -0,0 +1,20 @@ +from fastapi import HTTPException +from app.models.user import User +from database.queries.user import get_user_by_email, create_user_db + + +async def create_user(user: User): + result = get_user_by_email(user.email) + if result: + raise HTTPException(status_code=409, detail='User already exists') + + create_user_db(username=user.username, password=user.password, email=user.email) + created_user = get_user_by_email(user.email) + created_user_dict = { + "id": created_user[0], + "username": created_user[1], + "password": created_user[2], + "email": created_user[3], + } + + return {'user': created_user_dict} diff --git a/messenger_app/api/v1/endpoints/users/delete.py b/messenger_app/api/v1/endpoints/users/delete.py new file mode 100644 index 0000000..c3e9e14 --- /dev/null +++ b/messenger_app/api/v1/endpoints/users/delete.py @@ -0,0 +1,10 @@ +from fastapi import HTTPException +from database.queries.user import get_user_by_id, delete_user_db + + +async def delete_user(user_id: int): + user = get_user_by_id(user_id) + if user is None: + raise HTTPException(status_code=404, detail='User not found') + delete_user_db(user_id) + diff --git a/messenger_app/api/v1/endpoints/users/update.py b/messenger_app/api/v1/endpoints/users/update.py new file mode 100644 index 0000000..3eb2eee --- /dev/null +++ b/messenger_app/api/v1/endpoints/users/update.py @@ -0,0 +1,11 @@ +from fastapi import HTTPException +from app.models.user import User +from database.queries.user import get_user_by_id, update_user_db + + +async def update_user(new_info: User): + old_info = get_user_by_id(new_info.id) + if old_info is None: + raise HTTPException(status_code=404, detail='User Not Found') + update_user_db(user_id=new_info.id, new_email=new_info.email, + new_username=new_info.username, new_password=new_info.password) diff --git a/messenger_app/api/v1/models/__pycache__/__init__.cpython-310.pyc b/messenger_app/api/v1/models/__pycache__/__init__.cpython-310.pyc deleted file mode 100644 index 2cdda52cf1839ef7e155d1cde589870ae8a889e5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 165 zcmd1j<>g`kf^CI!QbF`%5P=LBfgA@QE@lA|DGb33nv8xc8Hzx{2;!HAenx(7s(xZ# zN>OU2zDs^`X>Mv>NwI!zYH@LDUV3T~f)$@wP@tb!kf~p0sGpmklA2SjA0MBYmst`Y ZuUAlci^B#eSelb+2eP4<2}rOo007OXD0u(? diff --git a/messenger_app/app/__pycache__/main.cpython-310.pyc b/messenger_app/app/__pycache__/main.cpython-310.pyc index bf436c0b421e4cc88b107dd4fdafa7a88eaee0ec..d2a10b07a64237a2e6682518d57ce64e6c82303f 100644 GIT binary patch literal 436 zcmZXRJxjzu5Qca2u}LK7fyIG8Ax(mXjfg0SVBrUfO`2o5or{s|ChR7n*IHj|Z|Ps! z*2=$NL4_y$wTpVMFu_m>eiRYjk|g>>Uy@K8oN?2hT%RK{U3V>L z>)#pBX2r6uKNH7#Eia5^jfQ3UWWx(Eh8JK~Q6@*cOd=aB(TO*ucF@_*kkZG!6qIP{ zQne->+_c+Y#skmCeY^igH@0@Vq0Owzo5pUJYEg9pM)95KDY_2j>ma+YC1hL)4P|y( uFFFaheRwIT0`xD<(JSjy@=~SEvkebrExHPh@JEP=vBV^%F=ftt=NLK^cU9CQ-=Tm diff --git a/messenger_app/app/main.py b/messenger_app/app/main.py index 86434cf..353da06 100644 --- a/messenger_app/app/main.py +++ b/messenger_app/app/main.py @@ -1,7 +1,8 @@ from fastapi import FastAPI -from api.v1.endpoints import users, messages +from api.v1.endpoints.users import router as users_router +from api.v1.endpoints.messages import router as messages_router app = FastAPI() -app.include_router(users.router) -app.include_router(messages.router) +app.include_router(users_router, tags=["Users"], prefix="/users") +app.include_router(messages_router, tags=["Messages"], prefix="/messages") diff --git a/messenger_app/app/models/__init__.py b/messenger_app/app/models/__init__.py new file mode 100644 index 0000000..a12278b --- /dev/null +++ b/messenger_app/app/models/__init__.py @@ -0,0 +1,2 @@ +from .user import User +from .message import Message diff --git a/messenger_app/app/models/__pycache__/__init__.cpython-310.pyc b/messenger_app/app/models/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ed7c75b767b47c254a91fc32314fc729170bd6c1 GIT binary patch literal 234 zcmd1j<>g`kg5aqOQ%!*MV-N=!FabFZKwK;XBvKes7;_kM8KW2(L2RZRrd;MIW+0n6 zm_d`}B_mLYCgUxZ(Bjl0AkFTZT3no%p6aK`a*L%DC{_eA>=t`2M7W3<$Xm%!#0I3m z#4lIMYlMLQj=3N Wf#MV2$1}Q2_GdI?ESTKFSOEY>!Wj(! delta 69 zcmey({D+x0pO=@50SNME&PiQ9k@u)9OG#=)$t}*})V!3`qWH{|Tiivd$*GxTV9vyk V@r>@10~rljGWE+0CpR-z002r97@hzC diff --git a/messenger_app/api/v1/models/__pycache__/user.cpython-310.pyc b/messenger_app/app/models/__pycache__/user.cpython-310.pyc similarity index 82% rename from messenger_app/api/v1/models/__pycache__/user.cpython-310.pyc rename to messenger_app/app/models/__pycache__/user.cpython-310.pyc index c80770156d2922c7588a4d7c2fb6f5e8b32b7e83..fe4dace754fc53507ee5b9aef87014a461eda9e4 100644 GIT binary patch delta 19 acmX@Xe3W^E3L~TAWK~8(#)8RFjClY#`~_kF delta 22 dcmX@ge1ds{3L~S-WK~8(mQ4LJ!^z={c>qfe1~dQw diff --git a/messenger_app/app/models/login.py b/messenger_app/app/models/login.py new file mode 100644 index 0000000..0a7cf28 --- /dev/null +++ b/messenger_app/app/models/login.py @@ -0,0 +1,6 @@ +from pydantic import BaseModel + + +class Login(BaseModel): + password: str + email: str diff --git a/messenger_app/api/v1/models/message.py b/messenger_app/app/models/message.py similarity index 66% rename from messenger_app/api/v1/models/message.py rename to messenger_app/app/models/message.py index 163006c..994ee8d 100644 --- a/messenger_app/api/v1/models/message.py +++ b/messenger_app/app/models/message.py @@ -3,7 +3,7 @@ from datetime import datetime class Message(BaseModel): - text: str - sender_id: int - receiver_id: int + conversation: str + sender: int + receiver: int timestamp: datetime diff --git a/messenger_app/api/v1/models/user.py b/messenger_app/app/models/user.py similarity index 100% rename from messenger_app/api/v1/models/user.py rename to messenger_app/app/models/user.py diff --git a/messenger_app/database/__init__.py b/messenger_app/database/__init__.py new file mode 100644 index 0000000..b5d8375 --- /dev/null +++ b/messenger_app/database/__init__.py @@ -0,0 +1,2 @@ +from .postgresql_database import postgresql_db_handler +from .mongodb_database import mongo_db_handler diff --git a/messenger_app/database/__pycache__/__init__.cpython-310.pyc b/messenger_app/database/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4ad340ff3b86f47e0823a268dae85a53eb00ddb6 GIT binary patch literal 282 zcmYjLI|{-;5Z%oN5m6At&I_b*FCZdlZDVJ%Y}_#k>?iKV!gF{6ORtpH$}3oi6ET>9 zdGqGYV`kiFG$0u7>kW=rA5GJZ2%8mVm?0>ls3wN)DQ$S9Bg6I#IopvWep0j~w4RnO zRGEix(n6&omsV-;I2apeGuP3!NnB65Zdu7x2Jp?*pB*=-R%R&QiSJ?g!fVZQXMp1c x4+Y=2!`XnX0yhu>*bMxi30aoB-Nc0`Y*7g@FE4d}VVpW^ST_HM7-2}p^aI|KPcHxf literal 0 HcmV?d00001 diff --git a/messenger_app/database/mongodb_database/__init__.py b/messenger_app/database/mongodb_database/__init__.py new file mode 100644 index 0000000..2dd56b3 --- /dev/null +++ b/messenger_app/database/mongodb_database/__init__.py @@ -0,0 +1,4 @@ +from .connection import MONGODB_CONFIG, MongoDbHandler + +mongo_db_handler = MongoDbHandler(**MONGODB_CONFIG) +mongo_db_handler.connect() \ No newline at end of file diff --git a/messenger_app/database/mongodb_database/__pycache__/__init__.cpython-310.pyc b/messenger_app/database/mongodb_database/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f3c79720c081873347055487603976db1a704545 GIT binary patch literal 309 zcmYjMy-ve05cWCYM-{F58ezaMfDnR+!ay>VDT|fFr`A$zM|L{!0*vqqRAS+kyfQJf zF>wJzIqAN;@AQ4TJ2#z97{$la79Xg-jpTo%M9wM0F@a(VI%c2(!z&I9xk@xcc!5W# z5=@@cEd!?bl4a>TkRju7c3T#UGQW_QWpQ=0AnxqS<;`_%RfoQKW!YYww9Z;=2korq zF{iPCF~Q-*^D2-7u8`@RsaA1 literal 0 HcmV?d00001 diff --git a/messenger_app/database/mongodb_database/__pycache__/connection.cpython-310.pyc b/messenger_app/database/mongodb_database/__pycache__/connection.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f649c6d326321d9f8422c8b20da3223010c2904e GIT binary patch literal 1398 zcmZWp&u`N(6n=J-H0`>dng(NGpE>}>wZ19!RGO;zNa?^a4ow@UpXkhZvK_a2%9O(-id2|&k~pMwryECS z2OpcGf+myDi4U%m9^TfR8@PVzif+}fiQ{V zT+8kLnem0_#GOot3ht5;cx>FuY;fncLfhl$kYVJwVd(%Bl9fuLG1$mZlrD@GH9lyjdg* z&kDILIc2<0NOrXR?p9to_)1bGw*$xWGp_aX>Y)U$ndLJ}q+-KFzQ!iTrF3#0E90qG znDb|_G0TFs8O8rch3ME*r*bC}4bXFF1}snHF50shEF7s!Os>Oy3`t26j}10w_P!li z4~kT-bbW*{Wg&WrJc-Dz2=VTu73DK}nKoS`SSPqgKzC>g=u9;cr(~@HKKRV{{ZhrV z<8}NK75isBx;(a=@LzFI-#^&f6}5x<^OyTJYHCHhfh`sPNuJkJ5+|jassJx=M&0|p G;{O9owm16# literal 0 HcmV?d00001 diff --git a/messenger_app/database/mongodb_database/connection.py b/messenger_app/database/mongodb_database/connection.py new file mode 100644 index 0000000..dbec5f7 --- /dev/null +++ b/messenger_app/database/mongodb_database/connection.py @@ -0,0 +1,36 @@ +from pymongo import MongoClient + +MONGODB_CONFIG = { + 'host': 'localhost', + 'port': 27017, + 'dbname': 'local', + 'collection': 'messenger' +} + + +class MongoDbHandler: + def __init__(self, dbname, collection, host, port): + self.host = host + self.port = port + self.dbname = dbname + self.collection_name = collection + self.client = None + self.collection = None + + def connect(self): + try: + self.client = MongoClient(self.host, self.port) + db = self.client[self.dbname] + self.collection = db[self.collection_name] + print("Connected to MongoDB") + except Exception as e: + self.collection = None + + def close_client(self): + if self.client: + self.client.close() + self.collection = None + print("MongoDB client closed.") + + def get_collection(self): + return self.collection diff --git a/messenger_app/database/postgresql_database/__init__.py b/messenger_app/database/postgresql_database/__init__.py new file mode 100644 index 0000000..20bd1fd --- /dev/null +++ b/messenger_app/database/postgresql_database/__init__.py @@ -0,0 +1,4 @@ +from .connection import POSTGRESQL_CONFIG, PostgreSQLHandler + +postgresql_db_handler = PostgreSQLHandler(**POSTGRESQL_CONFIG) +postgresql_db_handler.connect() \ No newline at end of file diff --git a/messenger_app/database/postgresql_database/__pycache__/__init__.cpython-310.pyc b/messenger_app/database/postgresql_database/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..baa338dd4594c2f685af357f76fa9346686c2771 GIT binary patch literal 323 zcmYjM%}N6?5Kgk|55-T#EZ&<&&VLfsj&M?Cff+C7G#L$WwRxwI|sZ0}~ zAM}M*8D#JIf>5GZNs9cNqM=}E|8`tH4DK(>yP-HAkFIV8NVyQF9+0}0RyE*9pQPAG zz1mp|b=1y!hHjrBq=R;;4o{6x6ERyl($=5YcNebU=aJ8x0gfsUnqRnjZotOC4TJ!8 u3VziI*|uECC?_%iUtjaj38AfyLL9fxY5T-DHE-awdn{}s?2%ozLw^BfK3RtV literal 0 HcmV?d00001 diff --git a/messenger_app/database/postgresql_database/__pycache__/connection.cpython-310.pyc b/messenger_app/database/postgresql_database/__pycache__/connection.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c9d98a704157ffcf5af4ba0660619c782c8b1870 GIT binary patch literal 1817 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