This shows you the differences between two versions of the page.
|
isi:laboratoare:06 [2025/11/09 22:39] alexandru.predescu [Obiective laborator] |
isi:laboratoare:06 [2025/11/15 10:58] (current) alexandru.predescu |
||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | ===== Laboratorul 06. Arhitectura client-server ===== | + | ===== Laboratorul 06. Arhitectura client-server. Python Flask ===== |
| ==== Obiective laborator ==== | ==== Obiective laborator ==== | ||
| Line 11: | Line 11: | ||
| * Cum funcționează cererile și răspunsurile (request-response cycle) | * Cum funcționează cererile și răspunsurile (request-response cycle) | ||
| - | === Scenarii din viața reală unde veți folosi asta === | + | === Exemple de aplicare === |
| La job: | La job: | ||
| Line 32: | Line 32: | ||
| * Dashboard-uri pentru crypto | * Dashboard-uri pentru crypto | ||
| * Orice idee de startup | * Orice idee de startup | ||
| - | |||
| În acest laborator veți înțelege **cum funcționează** cu adevărat o aplicație web. Veți scrie codul care procesează cereri, validează date, interacționează cu baza de date și returnează răspunsuri - toate acestea fiind componentele esențiale ale oricărei aplicații moderne. Veți dezvolta **o aplicație completă** folosind arhitectura client-server. În plus față de laboratoarele anterioare, veți crea un **backend REST API** în Flask care gestionează task-uri (adăugare, citire, actualizare, ștergere) și le stochează într-o bază de date SQLite. | În acest laborator veți înțelege **cum funcționează** cu adevărat o aplicație web. Veți scrie codul care procesează cereri, validează date, interacționează cu baza de date și returnează răspunsuri - toate acestea fiind componentele esențiale ale oricărei aplicații moderne. Veți dezvolta **o aplicație completă** folosind arhitectura client-server. În plus față de laboratoarele anterioare, veți crea un **backend REST API** în Flask care gestionează task-uri (adăugare, citire, actualizare, ștergere) și le stochează într-o bază de date SQLite. | ||
| Line 44: | Line 43: | ||
| - | === Arhitectura client-server === | + | ==== Arhitectura client-server ==== |
| Arhitectura client-server reprezintă un model de proiectare utilizat în dezvoltarea de aplicații distribuite. În acest model, două entități distincte comunică pentru a furniza funcționalitatea unei aplicații: **clientul** și **serverul**. | Arhitectura client-server reprezintă un model de proiectare utilizat în dezvoltarea de aplicații distribuite. În acest model, două entități distincte comunică pentru a furniza funcționalitatea unei aplicații: **clientul** și **serverul**. | ||
| - | == Clientul == | + | === Clientul === |
| Clientul este entitatea care inițiază cererea către server. De obicei, acesta este un utilizator final sau un dispozitiv care solicită resurse, date sau servicii de la server. Exemple de clienți includ browsere web, aplicații mobile sau desktop-uri. | Clientul este entitatea care inițiază cererea către server. De obicei, acesta este un utilizator final sau un dispozitiv care solicită resurse, date sau servicii de la server. Exemple de clienți includ browsere web, aplicații mobile sau desktop-uri. | ||
| - | == Serverul == | + | === Serverul === |
| Serverul este entitatea care procesează cererea primită de la client și oferă un răspuns adecvat. Serverele stochează resursele și datele necesare și gestionează logica de afaceri a aplicației. Un server poate servi mai mulți clienți simultan. | Serverul este entitatea care procesează cererea primită de la client și oferă un răspuns adecvat. Serverele stochează resursele și datele necesare și gestionează logica de afaceri a aplicației. Un server poate servi mai mulți clienți simultan. | ||
| Line 74: | Line 73: | ||
| * **Corpul răspunsului**, care conține datele returnate clientului (ex. un fișier HTML sau JSON). | * **Corpul răspunsului**, care conține datele returnate clientului (ex. un fișier HTML sau JSON). | ||
| - | + | == Ciclul Request-Responsee == | |
| - | === Request-response cycle === | + | |
| Mecanismul de bază în arhitectura client-server este **Request-response cycle**. | Mecanismul de bază în arhitectura client-server este **Request-response cycle**. | ||
| Line 84: | Line 82: | ||
| Acest proces permite interacțiunea continuă între client și server, fiecare cerere fiind procesată independent. | Acest proces permite interacțiunea continuă între client și server, fiecare cerere fiind procesată independent. | ||
| - | === Set-up === | + | == Endpoint-uri (rute) == |
| + | |||
| + | Un endpoint este o adresă URL la care serverul răspunde. În Flask: | ||
| + | |||
| + | <code python> | ||
| + | @app.route('/tasks', methods=['GET']) | ||
| + | def get_tasks(): | ||
| + | # Logica pentru a returna toate task-urile | ||
| + | return jsonify(tasks) | ||
| + | </code> | ||
| + | |||
| + | == Metode HTTP (verbe) == | ||
| + | |||
| + | * **GET**: Citește/Returnează/Afișează/Obține date (ex: obține lista de task-uri) | ||
| + | * **POST**: Creează/Postează date noi (ex: adaugă un task nou) | ||
| + | * **PUT**: Actualizează (Pune chestii noi peste) date existente (ex: marchează task ca finalizat) | ||
| + | * **DELETE**: Șterge date (ex: șterge un task) | ||
| + | |||
| + | == JSON - Formatul de Date == | ||
| + | |||
| + | Datele sunt trimise între client și server în format JSON (document): | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | "id": 1, | ||
| + | "title": "Învață Flask", | ||
| + | "completed": false | ||
| + | } | ||
| + | </code> | ||
| + | |||
| + | == Status Codes (coduri de răspuns) == | ||
| + | |||
| + | * **200 OK**: Cererea a fost procesată cu succes | ||
| + | * **201 Created**: Resursă nouă creată cu succes | ||
| + | * **400 Bad Request**: Date invalide trimise de client | ||
| + | * **404 Not Found**: Resursa nu există | ||
| + | * **500 Internal Server Error**: Eroare pe server | ||
| + | |||
| + | ==== Plan Laborator ==== | ||
| + | |||
| + | === Setup === | ||
| 1. Pentru a începe, asigurați-vă că aveți instalat [[https://www.python.org/downloads/|Python]]. | 1. Pentru a începe, asigurați-vă că aveți instalat [[https://www.python.org/downloads/|Python]]. | ||
| + | |||
| + | **Nu aveți Python?** > [[https://www.python.org/downloads/|python.org/downloads]] (bifați "Add to PATH" la instalare!) | ||
| 2. Verificați instalarea rulând comanda în terminal: ''python --version''. | 2. Verificați instalarea rulând comanda în terminal: ''python --version''. | ||
| 3. Descarcati scheletul de cod de [[https://github.com/ACS-ISI/Backend_Server|aici]]. | 3. Descarcati scheletul de cod de [[https://github.com/ACS-ISI/Backend_Server|aici]]. | ||
| + | |||
| + | <code bash> | ||
| + | git clone https://github.com/ACS-ISI/Backend_Server | ||
| + | cd Backend_Server | ||
| + | </code> | ||
| + | |||
| + | **Nu aveți git?** > Descărcați ZIP de pe GitHub > Extract | ||
| <note> | <note> | ||
| Line 116: | Line 163: | ||
| </note> | </note> | ||
| + | |||
| + | **Salvați fișierul după fiecare modificare. Serverul se restartează automat (debug mode).** | ||
| 4. Deschideti proiectul folosind IDE-ul preferat, de exemplu Visual Studio Code cu extensia Python sau un IDE specializat pentru Python, precum [[https://www.jetbrains.com/pycharm/|PyCharm]] și rulați comanda pentru instalarea dependențelor din fișierul //requirements.txt//. | 4. Deschideti proiectul folosind IDE-ul preferat, de exemplu Visual Studio Code cu extensia Python sau un IDE specializat pentru Python, precum [[https://www.jetbrains.com/pycharm/|PyCharm]] și rulați comanda pentru instalarea dependențelor din fișierul //requirements.txt//. | ||
| Line 128: | Line 177: | ||
| 5. Dupa finalizarea primului **TO DO** pentru testare descarcati postman de [[https://www.postman.com/downloads/|aici]]. | 5. Dupa finalizarea primului **TO DO** pentru testare descarcati postman de [[https://www.postman.com/downloads/|aici]]. | ||
| + | <note tip> | ||
| + | Tutorial testare cu Postman: | ||
| + | |||
| + | 1. **New Request**: | ||
| + | * Method: `PUT` | ||
| + | * URL: `http://localhost:5000/tasks/1` (înlocuiți `1` cu ID-ul unui task existent) | ||
| + | |||
| + | 2. **Body > raw > JSON**: | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | "completed": true | ||
| + | } | ||
| + | </code> | ||
| + | |||
| + | 3. **Send** | ||
| + | |||
| + | **Rezultat așteptat:** | ||
| + | |||
| + | <code json> | ||
| + | { | ||
| + | "id": 1, | ||
| + | "title": "Finalizează laboratorul", | ||
| + | "description": "Task 1 și Task 2", | ||
| + | "completed": true | ||
| + | } | ||
| + | </code> | ||
| + | |||
| + | </note> | ||
| + | |||
| <note tip> | <note tip> | ||
| Line 151: | Line 230: | ||
| === Task === | === Task === | ||
| - | Completati **TO DO**-urile din scheletul de cod, acestea sunt **self explanatory**. Scopul acestora este sa intelegeti cum sa interactionati cu o baza de date prin intermediul unui **server**. Prin aceste metode numite **endpoint-uri** puteti realiza comunicarea dintre client si server. | + | Completati **TO DO**-urile din scheletul de cod, acestea sunt **self explanatory**. Pentru paginare, puneti doi parametri: page (numarul paginii) si limit (numar de inregistrari per pagina). Scopul acestora este sa intelegeti cum sa interactionati cu o baza de date prin intermediul unui **server**. Prin aceste metode numite **endpoint-uri** puteti realiza comunicarea dintre client si server. |
| <note tip> | <note tip> | ||
| **Urmăriți comentariile din schelet** și tutorialul Flask-SQLAlchemy [[https://flask-sqlalchemy.readthedocs.io/en/stable/quickstart/|Quick Start]] pentru a implementa operațiile cu baza de date necesare pentru implementarea funcționalităților de lucru cu datele. Alternativ, folosiți direct biblioteca [[https://docs.python.org/3/library/sqlite3.html|sqlite3]] (vezi exemple în scheletul de cod) pentru a interoga baza de date folosind sintaxă SQL. | **Urmăriți comentariile din schelet** și tutorialul Flask-SQLAlchemy [[https://flask-sqlalchemy.readthedocs.io/en/stable/quickstart/|Quick Start]] pentru a implementa operațiile cu baza de date necesare pentru implementarea funcționalităților de lucru cu datele. Alternativ, folosiți direct biblioteca [[https://docs.python.org/3/library/sqlite3.html|sqlite3]] (vezi exemple în scheletul de cod) pentru a interoga baza de date folosind sintaxă SQL. | ||
| Line 189: | Line 268: | ||
| + | == Probleme Comune == | ||
| - | === [Q&A] === | + | Eroare: "ModuleNotFoundError: No module named 'flask'" |
| + | **Soluție**: Nu ai instalat dependențele. Rulează: | ||
| + | |||
| + | <code bash> | ||
| + | pip install -r requirements.txt | ||
| + | </code> | ||
| + | |||
| + | Eroare: "Address already in use" | ||
| + | **Soluție**: Portul 5000 este deja folosit. Oprește procesul anterior sau schimbă portul: | ||
| + | |||
| + | <code python> | ||
| + | app.run(debug=True, port=5001) | ||
| + | </code> | ||
| + | |||
| + | Eroare: "404 Not Found" când testezi în Postman | ||
| + | |||
| + | **Verificări**: | ||
| + | |||
| + | * Serverul Flask rulează? (vezi în terminal) | ||
| + | * URL-ul este corect? (ex: `http://localhost:5000/tasks`) | ||
| + | * Metoda HTTP este corectă? (GET, POST, etc.) | ||
| + | |||
| + | Date nu apar în baza de date | ||
| + | |||
| + | **Verificări**: | ||
| + | |||
| + | * Ai apelat `db.session.commit()`? | ||
| + | * Nu sunt erori în consolă? | ||
| + | * Verifică cu DB Browser dacă fișierul `tasks.db` există în folder-ul `instance` | ||
| + | |||
| + | |||
| + | ==== [Q&A] ==== | ||
| == De ce trecem de la Firebase la Flask? == | == De ce trecem de la Firebase la Flask? == | ||
| Line 208: | Line 319: | ||
| * **Flexibilitate la Baze de Date**. La Firebase: structură JSON, limitări la query-uri complexe, în timp ce la Flask + SQLAlchemy: orice bază de date (SQLite, PostgreSQL, MySQL, MongoDB), query-uri SQL complete, relații complexe | * **Flexibilitate la Baze de Date**. La Firebase: structură JSON, limitări la query-uri complexe, în timp ce la Flask + SQLAlchemy: orice bază de date (SQLite, PostgreSQL, MySQL, MongoDB), query-uri SQL complete, relații complexe | ||
| * **Integrări cu Servicii Externe** | * **Integrări cu Servicii Externe** | ||
| - | * **Costuri și Scalabilitate**. La Firebase: costuri cresc cu numărul de citiri/scrieri și trafic. Cân avem backend propriu: control total asupra infrastructurii și optimizări | + | * **Costuri și Scalabilitate**. La Firebase: costurile cresc cu numărul de citiri/scrieri și trafic. Când avem backend propriu: control total asupra infrastructurii și optimizări |
| **Comparație** | **Comparație** | ||
| - | | Aspect | Firebase | Flask Backend | | + | | **Aspect** | **Firebase** | **Flask Backend** | |
| | **Timp de setup** | 10 minute | 30-60 minute | | | **Timp de setup** | 10 minute | 30-60 minute | | ||
| | **Curba de învățare** | Ușoară | Medie | | | **Curba de învățare** | Ușoară | Medie | | ||
| Line 241: | Line 352: | ||
| * Planifici să scalezi aplicația | * Planifici să scalezi aplicația | ||
| * Vrei să înveți cum funcționează cu adevărat un backend | * Vrei să înveți cum funcționează cu adevărat un backend | ||
| + | |||
| + | |||
| + | ==== Resurse Utile ==== | ||
| + | |||
| + | == Documentație == | ||
| + | |||
| + | * [Flask Official Docs](https://flask.palletsprojects.com/) | ||
| + | * [Flask-SQLAlchemy Quickstart](https://flask-sqlalchemy.readthedocs.io/en/stable/quickstart/) | ||
| + | * [HTTP Status Codes](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status) | ||
| + | * [REST API Best Practices](https://restfulapi.net/) | ||
| + | |||
| + | == Tutoriale Video == | ||
| + | |||
| + | * [Flask Tutorial for Beginners](https://www.youtube.com/watch?v=Z1RJmh_OqeA) | ||
| + | * [Building a REST API with Flask](https://www.youtube.com/watch?v=s_ht4AKnWZg) | ||
| + | |||
| + | == Cheat sheets == | ||
| + | |||
| + | * [Flask Cheat Sheet](https://s3.us-east-2.amazonaws.com/prettyprinted/flask_cheatsheet.pdf) | ||
| + | * [SQLAlchemy Cheat Sheet](https://www.pythonsheets.com/notes/python-sqlalchemy.html) | ||