Salta al contingut principal

Projecte Flask + S3 #2: El cervell i la xarxa de seguretat

 


Aquesta és la segona part del projecte. Si has parat aqui et convido a consultar la primera entrada, on vam configurar l’entorn i vam establir els requisits previs. Ara passem a la implementació del codi.


Objectiu d’avui/Introducció

1
Documentar la creació del backend. Tot el desenvolupament del codi i que faré menció el podeu trobar al repositori corresponent al meu perfil de Git, o sigui que pots anar directament allà o obrir-lo a una finestra mentre veus els comentaris que descric. No vull deixar-me a aquesta introducció la importància que ha tingut pel bon i correcte desenvolupament del codi: 
La documentació oficial d’Amazon Web Services de Boto3 i les seves guies de millors pràctiques, per exemple.

La Classe S3Client i la seva importància

La finalitat de crear una classe S3Client com a façana/embolcall(més conegut com a Wrapper) és que amaga tota la complexitat de boto3. Faig un parèntesi, diguem que: 
Estem creant "un embolcall dins d’un altre embolcall". Si m’explico bé, és important entendre això: aquest S3Client més superficial simplificarà Boto3 que també es un embolcall gegantí que amaga tota la complexitat d’AWS. 
  • La nostra capa d’abstracció ens dóna una interfície senzilla. 
  • Boto3 és una altra capa que s’encarrega de tasques com la traducció a Python i peticions HTTP(entre d'altres). 
Ho encapsula i deixa tot net per a un següent pas sense estar contaminat amb l’altra lògica del projecte (la de Flask). Un altre objectiu que aconseguim si fem que tot passi per S3Client és que podem reutilitzar el codi si un dia pel que sigui decidim canviar la regió que té per defecte de l’S3. Al estar centralitzat, només hem de canviar un arxiu i no 10 o 20 en el cas que estigués tota la lògica repartida en altres arxius. 
A més a més, fa molt més fàcil el testeig(testing). Podem simular el comportament d’AWS(amb moto) dins d’aquesta classe sense haver d’interceptar la resta del codi. 
Aquesta organització que pot semblar una complicació al principi, ens estalvia hores de feina a llarg termini.
A cada mètode de la classe hem usat el bloc try/except ClientError de Boto3. Això fa que el codi no col·lapsi en cas d’algún problema de xarxa amb AWS o hi han permisos inadequats. Això fa que et retorni un valor segur com es False o una llista buida. És una recomanació de la documentació oficial
D’altra banda quan utilitzem os.path.basename ens garanteix que només utilitzem el nom del fitxer final ex. “test_file.txt” i no deixa pujar d’altres amb un nom maliciós. Garantint una lògica d’execució. 
Testing de qualitat 

Un cop escrit tot el programari ens trobarem amb la pregunta de si tot funciona correctament i no em refereixo en el clàssic de donar-li tot el codi a ChatGPT, Gemini, Deepseek, etc. per si troba alguna errada al codi. En el meu cas vaig crear una carpeta anomenada scripts que em va fer d’una mena de pont entre el codi i els tests unitaris que faria com a final de desenvolupament del backend. 
Els scripts que vaig anar escrivint tenien l’objectiu de fer proves manuals o demostracions ràpides i són útils per verificar si la configuració d’AWS es correcta. Els scripts verifiquen la connexió real amb AWS i els tests verifiquen que el codi funciona correctament
Aquests scripts només criden mètodes de classe S3Client i no tenen lògica de boto3. 
Deixant de banda els scripts o petits tests. Anem a la problemàtica que seria “Com provem aquesta classe S3Client?" sense que:
  • Ens generi despeses a la factura d’AWS. 
  • Depenguem de la velocitat d’Internet i latència. 
  • Modifiquem o esborrem dades reals sense voler. 
Per resoldre aquests punts tenim dues eines anomenades: Pytest i Moto, aquestes fan simulacions o com diuen professionalment en anglès “Mocking”. 
-Pytest és el marc de proves que utilitzem per a estructurar i executar els tests de manera fiable. Què és un marc de proves(framework)? És un conjunt d’eines que faciliten les proves automàtiques per veure si funciona de manera corresponent, en aquest cas aquesta eina funciona per a Python. Amb aquesta executes els teus tests. 
-Moto és una llibreria que simula els serveis d’AWS. Amb aquesta pots crear versions “falses”(que realment no es creen) interceptant les crides que Boto3 fa a AWS i simulant l’entorn a la memòria del teu ordinador. 
En el meu cas quan he fet després d’haver importat mock_s3 i pytest: 
    @pytest.fixture
    def s3_client():
    with mock_s3():
    client = S3Client(region_name="eu-west-1")
    client.create_bucket("bucket-prueba")
    yield client
He creat una fixture de pytest amb el decorador mock_s3(). La fixture prepara quelcom que necessitem abans per executar el test. En aquest cas un client s3 fals. I el decorador afegeix un comportament extra a una funció. Li estem dient que la informació que posem a continuació la interpreti d’una manera determinada com si fos “mock_s3”. 
Quan escrivim yield assegurem que cada test unitari s’executa en un entorn AWS fals, es crea i s’esborra de la memòria de l’ordinador. 
Un altre detall és l’ús de la funció de Pytest tmp_path que ens permet crear fitxers temporals falsos i ens serveix per exemple per simular la pujada d’aquests i esborrar-los un cop acabat el test, no deixant residus al sistema.
Per que tot funcioni hem de seguir un patró anomenat AAA(Arrange-Act-Assert). Vol dir: 
-Preparar(Arrange): 
Ho deixem tot enllestit per realitzar la prova. Crear objectes, preparació de l’entorn… 
-Actuar(Act): 
Executem l’acció a provar. Cridar una funció, fer una petició a un servei… 
-Assert(Comprobar): 
Verificar i contrastar els resultats. Si coincideixen funciona, sinó falla. 
D’aquesta manera em dono per satisfet, havent assolit l’objectiu de tancar el cicle del backend amb èxit.

Comentaris

Entrades populars d'aquest blog

Projecte Flask + S3 #3: Del servidor local a S3

  Aquesta és la tercera part que parlo del projecte. Si encara no estàs seguint-lo, et recomano que miris les entrades anteriors dedicades al tema. A la primera part vam configurar l’entorn i decidir les pautes. A la segona , dedicàrem el seu temps a la importància de fer una bona classe S3Client i uns tests de pytest correctes. A l’hora de pensar en desenvolupar l’app , hem de canviar la manera de pensar. Passem d’una filosofia de backend en la que pensem únicament en Python - A una full-stack amb Flask. Què és un full-stack ? La seva traducció literal és una “pila complerta”, es refereix a quan en programació s’escriu un codi des de zero. I disposa de tres parts:  Front-end , la interfície d'usuari, és el que interactua directament des del seu dispositiu i en el nostre cas és HTML/Jinja2. Back-end , el cervell que s'encarrega de processar les peticions del Front-end, executar la lògica de l’aplicació, les autoritzacions i la connexió amb la base de dades. Base de dades , ...

A la vigesimoséptima, va la vencida

  Ayer sentía que estaba bien con Linux Mint pero a la vez lo veía demasiado cerrado y probé OpenSuse Leap(no me convenció) y hoy vuelvo a intentar instalar Fedora Workstation 42. Eh! Y Linux Mint lo recomiendo 100% para todo el mundo. Según yo mismo, la semana pasada no me funcionó Fedora por el tema de la BIOSLegacy. No le voy a dar más vueltas no es un portátil viejo pero por lo que sea ésta BIOS es la única manera que tiene de funcionar con Linux y un disco duro externo. En realidad no pasa nada (mientras nos quede Windows). Equisde que he estado rajando de Fedora cuando va de puta madre solo que no lo configure bien, no haría honor al nombre del blog sinó. De hecho empiezo a pensar que a lo mejor el UEFI sí funcionaría pero la lié al instalar, de momento lo voy a dejar así con MBR. Bof, empecé por la mañana y todo bien, mi error ha sido al querer instalarle los drivers de Nvidia, ha tenido un conflicto con Nouveau. A veces es mejor dejar las cosas como están. Si fuera mi único...