From 84fbf4d7a403907b642a50634233b2e192a86dbb Mon Sep 17 00:00:00 2001 From: kaykayag Date: Sat, 20 Sep 2025 02:06:30 +0800 Subject: [PATCH] chore: added activity details file --- .gitignore | 1 + app.py | 23 ++++++++ controller/__init__.py | 1 + .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 245 bytes .../library_controller.cpython-313.pyc | Bin 0 -> 3522 bytes controller/library_controller.py | 50 ++++++++++++++++++ instance/library.db | Bin 0 -> 12288 bytes models/__init__.py | 3 ++ models/__pycache__/__init__.cpython-313.pyc | Bin 0 -> 271 bytes models/__pycache__/library.cpython-313.pyc | Bin 0 -> 1057 bytes models/library.py | 14 +++++ python-flask-api | 1 + repositories/__init__.py | 1 + .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 216 bytes .../library_repository.cpython-313.pyc | Bin 0 -> 2333 bytes repositories/library_repository.py | 38 +++++++++++++ requirements.txt | Bin 0 -> 584 bytes service/__init__.py | 1 + service/__pycache__/__init__.cpython-313.pyc | Bin 0 -> 205 bytes .../library_service.cpython-313.pyc | Bin 0 -> 1695 bytes service/library_service.py | 29 ++++++++++ 21 files changed, 162 insertions(+) create mode 100644 .gitignore create mode 100644 app.py create mode 100644 controller/__init__.py create mode 100644 controller/__pycache__/__init__.cpython-313.pyc create mode 100644 controller/__pycache__/library_controller.cpython-313.pyc create mode 100644 controller/library_controller.py create mode 100644 instance/library.db create mode 100644 models/__init__.py create mode 100644 models/__pycache__/__init__.cpython-313.pyc create mode 100644 models/__pycache__/library.cpython-313.pyc create mode 100644 models/library.py create mode 160000 python-flask-api create mode 100644 repositories/__init__.py create mode 100644 repositories/__pycache__/__init__.cpython-313.pyc create mode 100644 repositories/__pycache__/library_repository.cpython-313.pyc create mode 100644 repositories/library_repository.py create mode 100644 requirements.txt create mode 100644 service/__init__.py create mode 100644 service/__pycache__/__init__.cpython-313.pyc create mode 100644 service/__pycache__/library_service.cpython-313.pyc create mode 100644 service/library_service.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b694934 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.venv \ No newline at end of file diff --git a/app.py b/app.py new file mode 100644 index 0000000..6900fa0 --- /dev/null +++ b/app.py @@ -0,0 +1,23 @@ +from flask import Flask +from flask_restful import Api +from models import db +from controller import LibraryListResource, LibraryResource + +app = Flask(__name__) +api = Api(app) + +app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///library.db' +app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False + +db.init_app(app) + +@app.before_request +def create_tables(): + db.create_all() + + +api.add_resource(LibraryResource, '/api/library/') +api.add_resource(LibraryListResource, '/api/library') + +if __name__ == '__main__': + app.run(debug=True) \ No newline at end of file diff --git a/controller/__init__.py b/controller/__init__.py new file mode 100644 index 0000000..5c80529 --- /dev/null +++ b/controller/__init__.py @@ -0,0 +1 @@ +from .library_controller import LibraryListResource, LibraryResource \ No newline at end of file diff --git a/controller/__pycache__/__init__.cpython-313.pyc b/controller/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7d126bbf7c0bcc9c61b93243254492402e29f8e6 GIT binary patch literal 245 zcmey&%ge<81iO3BX1D<9#~=<2FhLogMSzT{48aV+jNS}hj75xIOhrrz4Czdo%r6;% zQkqP+gncrTiV}+|eKLznf>Mj~ON)|IZ}CF~VFG@d%(sMcAPVD?^YcoI@^f-hi;9?m zW)!giiIohWfh5B%GiR%q(Bjmh;uxRQy!^8K7?=Fy(%jU%lH!=OoW$ac7=-4S`1s7c u%#!$cy@JYH95%W6DWy57c14^(V?a(T<^~cUm>C%v?=!euU~nm72l4@kfJDpy literal 0 HcmV?d00001 diff --git a/controller/__pycache__/library_controller.cpython-313.pyc b/controller/__pycache__/library_controller.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dafc11a8b9946686ce7642d3fdd9753433d39793 GIT binary patch literal 3522 zcmb_fT}&L;6~6PgGrL~1B!j&e%P=esW)lOZfJsuv4H#DmIM~_|RU}rL4!g6k@puN` zJL|@7)TVi;i29I3tsSdReyJ4qr94$?pN!iF=ONM<5Oe+$UpF-R-~%3`BP9X6P@VXB$?nSr=iYI z@)H6TLS2{?CnPF`x;Pn|kg2SZR+1sQ)JF7Jo*NdTwWt!d%FwE8YmLvvvxyBHlH~#= zXEC=z3l``ywa!;8=7HLDsys_gdQrFNg>u-*7iSC6vXSJfADbE|mr0&bPA8PtIV$LU z8=;~ufRuER#^$7KEKsW}o+>l1w&w;IffQ;h;eu!dJpJY+5SPge$f)G_nzmJE$Z++; z;ifs2{DfzGKViH|UU-}kHLLChXwg@RWcjI$TQDmt zP+TLB=Pb`KZ99-X*C>_?URDT1X4$1cnswc?ED*yAPp)ZN@cfBq^V7_tEPu*!+zW1g z+$~hjS&ql@CEH~4`GV_s)U|Dk=IzMP##U3`!o@&<4TE$8ll4J|4BM~)5U-Ov&FyQ= z-7C%AtIa)&(#KC7SxpW6aroNMyUBNwSDLO5-%brI4f?60zH;>6E2#k{!mQu#ds=L4 z^dEyOE|d1}WcD6d5sL{X*TD@xgf)su(D|wkKGuauH&GXL=?JIC(BLz8oUr5&2|G%L zOmo9ka5(%lpNsDp0G~Ag=rXR?NoK+T!*Mb(pC-f+X5cJQ$u-rqtvdJEmR{3pYibZS zGit4MTBw~xkN5F0dXInwcta$S- z4dincW9FQ7Dfyyv!L-Xot!R2?`E9u8#{00>gVt%sdUe4ncvexfD0Qjk777(=6|eJw z6gC8M(Sj*9+qeg_vI&Y-3>1XuE6jBw#KsELGChm##=iK;R}0pHSB6fsb09M~1bhVw zf^gO>oDBr#(X2?(M1hD$qRpssRtOmYwMNlYfwe2UFR`>TVrEiF<1LL<8|Kh|uUp@U%^7Mc1N;vcZ%fQjz7#wXUe?A0axjiwa3Clgb zWBY}hdpOWLaD0P>h#+RvkTja6$uP~n|8SFH_`9I@mXVnB3wo1 zbRMEyz^H`CeFPEfB96&QQxs40plJ;FRC8QUE4dY?xbZuHI7L*|s5p)|pS@_5iy^k5 z88J)upg_p7DhWsCMR(LwPwn2wq5E*?2ngWN)Pc3sp_SC3_r%py@1po=N?mU`;CJ-< z>XD@`Umf<7!|N&at=Has?Ki);%KTKuS2Cev9a88QY835;B2NO4pQ84~Jk45>sOr$gWbikus|nYN*} zA4NNeD!b7RYzR|vtg-;~6cHQk#Ab{fih)hLP#gr2mA0Yc32a4ZP>dFat013M2~Ak2 zcwa>bG~$-*S0Iqel&?_Po$U-Yv^f5$ng$Z{y9WLA&{DxqKjSw)^M7Tnkti66 zlZmk=VR>)wSX{U%aG>9eOCTGg@e8=Yw?X5#i)Dywahhv_r{Qyg@j9j&XWhh3OkGNiojyIO{jBWGYcJ|!Q`#j( zD_XV%*|j0u?MXyqrNkNq43f=dp;^>D&# z2&a|<*E*J3mSRiue#eh|_4ymXPAC23$?usAF~Hu)^piit`^ldYqXWWUdPffn%iSEP z%ZDY9VYZseDiqI4pF(jMMK6jl)jf+E-jw#C!0Z;~EPO3ce58f~xt-x#3bUIib$ywP zLw38rSE=VX96FUv1iSHteAb}wKcrN#DYAJWg>BJ02i`8>Uy`b$ATL`si#Pz07H#?P zF#_dSl)jJC6EFnmnJ~P;U4i4cPe|qyvM-c-?upIZ8SZM&J%aVUgKZ$+p1)794sZ2e DajU%X literal 0 HcmV?d00001 diff --git a/controller/library_controller.py b/controller/library_controller.py new file mode 100644 index 0000000..698fab6 --- /dev/null +++ b/controller/library_controller.py @@ -0,0 +1,50 @@ +from flask_restful import Resource +from flask import request +from service import LibraryService +from models import db + +class LibraryListResource(Resource): + def get(self): + books = LibraryService.get_all() + return [book.to_dict() for book in books], 200 + + def post(self): + try: + data = request.get_json() + + if not data or 'isbn' not in data or 'title' not in data or 'author' not in data: + return {'message': 'Invalid data'}, 400 + + book = LibraryService.create(data) + return book.to_dict(), 201 + except Exception as e: + db.session.rollback() + return {"error": "Unexpected error occured", "details":str(e)}, 500 + +class LibraryResource(Resource): + def get(self, isbn): + book = LibraryService.get_by_id(isbn) + if not book: + return {'message': 'Book not found'}, 404 + return book.to_dict(), 200 + + def put(self, isbn): + try: + data = request.get_json() + book = LibraryService.update(isbn, data) + if not book: + return {'message': 'Book not found'}, 404 + return book.to_dict(), 200 + except Exception as e: + db.session.rollback() + return {"error": "Unexpected error occured", "details":str(e)}, 500 + + def delete(self, isbn): + try: + book = LibraryService.delete(isbn) + if not book: + return {'message': 'Book not found'}, 404 + return {"message": f"BOOK with ISBN {isbn} deleted"}, 200 + except Exception as e: + db.session.rollback() + return {"error": "Unexpected error occured", "details":str(e)}, 500 diff --git a/instance/library.db b/instance/library.db new file mode 100644 index 0000000000000000000000000000000000000000..2a2711cc2a7736c8b5d5d504e5a0fc2a838f4295 GIT binary patch literal 12288 zcmeI#zi-n(6bJD0uRtPIN2d-|^fIowUiH!*fiG?$2T~LL(At8OAboM*HyJ!2e-RORlYDtG#K2J1t*#%}<>;@5I ztY(H|#&K9CagQhFUe3>o8oTzcwZy+Oo3Apy%0Hg90d)vK00Izz00bZa0SG_<0uX?} zKNfhiVVzs?ee3O-PNqt#bebo5DvK(y2XPpTLmCHLQApKeYBuU=F$joaiT}P4;U(sXlBXs{ZT;AX4E2#_8`70{2xzw|C@rV}kh0N3agyjA#c`jdHa^2;gFWS4oXdK4d z!&^i*qhPc{qAl(WDA1`=*%im-*Dv>yc~WSz+q5}UN%6Q`(>YpHBnK+HXuG_--Z|-Y z)JmMRda`brHNH5t=C{{1%>Q`&Gvhz_7ygZZH7NoD5P$##AOHafKmY;|fB*y_0D=Eb Zz;n3O_iE0vCE9K|={e=KW4jKoi=SjAi(&u( literal 0 HcmV?d00001 diff --git a/models/__init__.py b/models/__init__.py new file mode 100644 index 0000000..a499d70 --- /dev/null +++ b/models/__init__.py @@ -0,0 +1,3 @@ +from flask_sqlalchemy import SQLAlchemy +db = SQLAlchemy() +from .library import Library \ No newline at end of file diff --git a/models/__pycache__/__init__.cpython-313.pyc b/models/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ea0f97c858dbdfcc11b00fb4bb00f8f42c1a5c17 GIT binary patch literal 271 zcmey&%ge<81O^>vGa`WWV-N=hn4pZ$T0q8BhG2$ZMsEf$#v(=qh8RXA22-eX5mPWz zFtaza7fTU~0z*2BChJR(j3(nPuHZl)$DHJh)ZEIKj1VDqpUkA9#G*<+P1aiiX*r3- z+404NIf)QOMa)1&x0q6rZn5V;lohc8MOHF=29gZ7jGV1vLW@(2ier3I^YY8`V_fo+ zOLJ56N{VAZCS}Cr=BK3Q6vxEJXXa&=#K-FuRNmsS0ScDpq}mnn0F3}SqF4w>d|+l| WWW39uev_5IIi`W>9)nB~C>#JGC`Cj7 literal 0 HcmV?d00001 diff --git a/models/__pycache__/library.cpython-313.pyc b/models/__pycache__/library.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ef0c5d110e66bfbd582e254fafc0f551680c8765 GIT binary patch literal 1057 zcmbtSzfaph6n_4dA5Kgn3W&0lqAppGDm4SB>H*BrR=?n1GI>x>Ki`4`|kOB@4mafVd%gk|M5$$EdhKN zi>uIvNq?Rv$AADyFJM_B(lkuM3?O+5kYY+@_3DS4Z&8VJqU@*zt;dz2ATfE%uHMuD zTsQc^*<&z)NC=3GB%&ahsHRrV{#hR9Gr;+gyLhA&MI#D_6jw<9 zw}Ot+Q$R9EC)u4$AmuiIXWm z@;uA-oa*p|oCgrb3z_~hhhx})GXLHV&dRqr5Vdz)87djdzu(zB*z8VBb#@PSeZ3E*__!;k$!DS>C z0xzojEP+De`a48CGLjRJ7jTaQ8^@T2R_Io-74j-O3LT0unGglz0!9UhhdltHOV>HP zgYMXa=4v-%wC48b+T~8=u=0r3j(g~y$Vc^4=REtQ`Mhi7 zT9y4un{*n7jg!%%x2Ms$QEV<VNJ$c zfn9$7R0)+zgvup}DpeIL7QzIofv*hsG4Ry^KMuZD z)tBT_EK9yr`}-0Qj}PP}OFB)hC-O-?9yV08w>;+f9__rucK+2Lo(6-xd!Y771#}?A z@SKs4-=a3?1$NZO0(mB_<`s&Aq%T=yC2VIu!{`Gabi*_2i9+bwU~tA66u z+fBRWv+9~_v5hK?x^!$-b%Rlw{b1+rR)_0rPOD);QJy__w7bz7Ho$IxdQAQ>CiWif zJ~}pXFO1xwG51`bqoc4=mq0~=rxz3W2#o(TfifwC^%e+CK#_0?6xqg=b=%KNTyG$N$Le0Q>4@pnJa2PwIx4faZ9Z{+E*KwyQfv_vOhixa zC3lm1W4mKd{3HG5Y2Y90(=YVtBYoz?NbjV?gt*$Ue5*dl>KK#|$o~z-)#lWa%QC(k zC=Eb)os^~GC9_GBPv;3~LpNJX737SN&*!7prC$p&9su~2)LBkhEnwFmIr88gLQ?Rp z;7o)RkzGSl93KjRJAjfLp_CA}SMZizha9dszTIRzzF{%T_bKA%qao0wNJ=^lDzDKr z+HaxCg5t`i-Qn7{<+g2xk46q9Abza91xVO@>O8o?3O38W0Cf@JchsMa^htX1*X-=~ zcfP&z-Fv$$JIklW#1sG6xOHgUI=wb|pgt}9bS?i%BQuMC>LiguhFrjii(i2s;fJrt z1*t6c@e^FAAk%~t@iq@hv5)Q9LRpI56u|cK-T0sl$pE%egl&8X+cOAxtYN#hZwFAy z0hEX$!^;xFM)AH~gjuk67SoqOU4~hBSpz5z7LN3{-+Wyu5_&a1!gbSZSxwtCdD1kS zUZd@zJz|;<+m;)y7^b=AQ0BW%3;tVhnE_3mdeindyaqL(6wRQT0R<0%Q}^it`r=SG zOfyI~k=jnJ?c2;WMFZmH5VWNTf>3z(*e0m2$cZ-oN|vrA6pD# zik1muV0Cq|BdKK$mU;v};SyNgDN!OG#(FYXK_A${YF_0r7=!Jy06{hCYp7wae;7>b e9(^BDfQN+Po$e}h5W|5E3r%xeNl6#oZ@ccQ-l literal 0 HcmV?d00001 diff --git a/repositories/library_repository.py b/repositories/library_repository.py new file mode 100644 index 0000000..7fecdda --- /dev/null +++ b/repositories/library_repository.py @@ -0,0 +1,38 @@ +from models import db, Library + +class LibraryRepository: + @staticmethod + def find_all(): + return Library.query.all() + + @staticmethod + def find_by_id(isbn): + return Library.query.get(isbn) + + @staticmethod + def save(book): + db.session.add(book) + db.session.commit() + return book + @staticmethod + def update(isbn, data: dict): + book = Library.query.get(isbn) + if not book: + return None + + for key, value in data.items(): + if hasattr(book, key): + setattr(book, key, value) + + db.session.commit() + return book + + @staticmethod + def delete(isbn): + book = Library.query.get(isbn) + if not book: + return None + + db.session.delete(book) + db.session.commit() + return book \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..76e3ef55bc1abc767f150bd8028153eda0c4b1c1 GIT binary patch literal 584 zcmZ`$%TB{U5c3&{Poc`DP|AS=2RI-&K#@425SCC%lPC|V@bQ2>)2O-m({)LuBUcC1Jzq|S>b{EH{7M{Qf}<6 YRQfZ)_PYALrC!lhr28tlmJ8SY1}=J1>Hq)$ literal 0 HcmV?d00001 diff --git a/service/__init__.py b/service/__init__.py new file mode 100644 index 0000000..dd29aff --- /dev/null +++ b/service/__init__.py @@ -0,0 +1 @@ +from .library_service import LibraryService diff --git a/service/__pycache__/__init__.cpython-313.pyc b/service/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..36d25a940b00ad3843a1b2ca741e0329873d423e GIT binary patch literal 205 zcmey&%ge<81a~{mX6ORx#~=<2FhLog1%QmH48aV+jNS}hj75wJ4Czdo%r6;%!kUb? z_k~%s{0p89oC^hFiwYRxzPKiQ*Wa)V%z% z{1}(~C%v?=ff>u>m;%F1I$B literal 0 HcmV?d00001 diff --git a/service/__pycache__/library_service.cpython-313.pyc b/service/__pycache__/library_service.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f5dc12fe7ecb098fac480f7f299c4aae8ef6872f GIT binary patch literal 1695 zcmb_c%}?A$6rb_enhnH23PC7RwFzw{NBg7KQ>lpxc+$k ze&d6|*l%PEmQ^bKJE-ijfCc<1d%}S?NH?AuPfRcyY=+ITz?@})wS*_o0&Cs&ozJBD zTu(fU+YrLeirh+7oTadXV66l@=j9Io+dV-BMURl`= z+SZU=L)#v*U9_DcdnBkqeckm(^yQLBAYnW1$j_AYIZ`Hq{o6UI=OqQkRt9t{gkdEH zl&-UVzU&)7q1s)GyO9W!WS{lPTR;5aVQW=MP_1XOn{KDA$7!dxDZ80!ttFw_XyG2w zX(dJNL}@p-c64oBW^|UG{x|hziQ9OAnn3Y0``v4N^!!85Kl0`e+<6#9w8K#h7O~5d zYofBp{wujvwp2!6XE1^xg9Ph&g6$m>-u%1AN8a57_wIS(4m#$XVx5B z<);by_A(G3ZD(?zQ8|={K)-7mlx7{ng!l^rdEv*I!$I)!F!W zAH5rg-i^1>aCfT&@f4!D7|F2rUU^%BxYg?QNulXAxsVl4)hC2<$uH*Kpd%;L_b#1V?%G9Crrkhn&I>Q{0T zqHq*pmO}}ZTu_5mgyI)=Y)^bKxP7~CGH3FHv=aw4!tPbry%KXO zKh#dfOTWd+Z?TGP=2#z3X%+hy4Q literal 0 HcmV?d00001 diff --git a/service/library_service.py b/service/library_service.py new file mode 100644 index 0000000..f765e95 --- /dev/null +++ b/service/library_service.py @@ -0,0 +1,29 @@ +from repositories import LibraryRepository +from models import Library + +class LibraryService: + @staticmethod + def get_all(): + return LibraryRepository.find_all() + + @staticmethod + def get_by_id(isbn): + return LibraryRepository.find_by_id(isbn) + + @staticmethod + def create(data): + book = Library( + isbn=data['isbn'], + title=data['title'], + author=data['author'] + ) + return LibraryRepository.save(book) + + @staticmethod + def update(isbn, data): + return LibraryRepository.update(isbn, data) + + @staticmethod + def delete(isbn): + return LibraryRepository.delete(isbn) + \ No newline at end of file