Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 57f638d

Browse files
committed
Backend: Día 5
1 parent 3445755 commit 57f638d

15 files changed

+132
-19
lines changed
113 Bytes
Binary file not shown.
Binary file not shown.

Backend/FastAPI/db/client.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Clase en vídeo (22/12/2022): https://www.twitch.tv/videos/1686104006
2+
3+
### MongoDB client ###
4+
5+
# Descarga versión community: https://www.mongodb.com/try/download
6+
# Instalación:https://www.mongodb.com/docs/manual/tutorial
7+
# Módulo conexión MongoDB: pip install pymongo
8+
# Ejecución: sudo mongod --dbpath "/path/a/la/base/de/datos/"
9+
# Conexión: mongodb://localhost
10+
11+
from pymongo import MongoClient
12+
13+
db_client = MongoClient()
Binary file not shown.

Backend/FastAPI/db/models/user.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Clase en vídeo (22/12/2022): https://www.twitch.tv/videos/1686104006
2+
3+
### User model ###
4+
5+
from pydantic import BaseModel
6+
7+
8+
class User(BaseModel):
9+
id: str | None
10+
username: str
11+
email: str
Binary file not shown.

Backend/FastAPI/db/schemas/user.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Clase en vídeo (22/12/2022): https://www.twitch.tv/videos/1686104006
2+
3+
### User schema ###
4+
5+
def user_schema(user) -> dict:
6+
return {"id": str(user["_id"]),
7+
"username": user["username"],
8+
"email": user["email"]}
9+
10+
11+
def users_schema(users) -> list:
12+
return [user_schema(user) for user in users]

Backend/FastAPI/main.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
# Instala FastAPI: pip install "fastapi[all]"
88

99
from fastapi import FastAPI
10-
from routers import products, users
10+
from routers import products, users, basic_auth_users, jwt_auth_users, users_db
1111
from fastapi.staticfiles import StaticFiles
1212

1313
app = FastAPI()
@@ -16,6 +16,11 @@
1616
app.include_router(products.router)
1717
app.include_router(users.router)
1818

19+
# Routers - Clase en vídeo (22/12/2022): https://www.twitch.tv/videos/1686104006
20+
app.include_router(basic_auth_users.router)
21+
app.include_router(jwt_auth_users.router)
22+
app.include_router(users_db.router)
23+
1924
# Recursos estáticos - Clase en vídeo (14/12/2022): https://www.twitch.tv/videos/1679022882
2025
app.mount("/static", StaticFiles(directory="static"), name="static")
2126

Binary file not shown.
Binary file not shown.
Binary file not shown.

Backend/FastAPI/routers/basic_auth_users.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22

33
### Users API con autorización OAuth2 básica ###
44

5-
from fastapi import FastAPI, Depends, HTTPException, status
5+
from fastapi import APIRouter, Depends, HTTPException, status
66
from pydantic import BaseModel
77
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
88

9-
app = FastAPI()
9+
router = APIRouter()
1010

1111
oauth2 = OAuth2PasswordBearer(tokenUrl="login")
1212

@@ -66,7 +66,7 @@ async def current_user(token: str = Depends(oauth2)):
6666
return user
6767

6868

69-
@app.post("/login")
69+
@router.post("/login")
7070
async def login(form: OAuth2PasswordRequestForm = Depends()):
7171
user_db = users_db.get(form.username)
7272
if not user_db:
@@ -81,6 +81,6 @@ async def login(form: OAuth2PasswordRequestForm = Depends()):
8181
return {"access_token": user.username, "token_type": "bearer"}
8282

8383

84-
@app.get("/users/me")
84+
@router.get("/users/me")
8585
async def me(user: User = Depends(current_user)):
8686
return user

Backend/FastAPI/routers/jwt_auth_users.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
### Users API con autorización OAuth2 JWT ###
44

5-
from fastapi import FastAPI, Depends, HTTPException, status
5+
from fastapi import APIRouter, Depends, HTTPException, status
66
from pydantic import BaseModel
77
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
88
from jose import jwt, JWTError
@@ -13,7 +13,7 @@
1313
ACCESS_TOKEN_DURATION = 1
1414
SECRET = "201d573bd7d1344d3a3bfce1550b69102fd11be3db6d379508b6cccc58ea230b"
1515

16-
app = FastAPI()
16+
router = APIRouter()
1717

1818
oauth2 = OAuth2PasswordBearer(tokenUrl="login")
1919

@@ -86,7 +86,7 @@ async def current_user(user: User = Depends(auth_user)):
8686
return user
8787

8888

89-
@app.post("/login")
89+
@router.post("/login")
9090
async def login(form: OAuth2PasswordRequestForm = Depends()):
9191
user_db = users_db.get(form.username)
9292
if not user_db:
@@ -105,6 +105,6 @@ async def login(form: OAuth2PasswordRequestForm = Depends()):
105105
return {"access_token": jwt.encode(access_token, SECRET, algorithm=ALGORITHM), "token_type": "bearer"}
106106

107107

108-
@app.get("/users/me")
108+
@router.get("/users/me")
109109
async def me(user: User = Depends(current_user)):
110110
return user

Backend/FastAPI/routers/users_db.py

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# Clase en vídeo (22/12/2022): https://www.twitch.tv/videos/1686104006
2+
3+
### Users DB API ###
4+
5+
from fastapi import APIRouter, HTTPException, status
6+
from db.models.user import User
7+
from db.schemas.user import user_schema, users_schema
8+
from db.client import db_client
9+
from bson import ObjectId
10+
11+
router = APIRouter(prefix="/userdb",
12+
tags=["userdb"],
13+
responses={status.HTTP_404_NOT_FOUND: {"message": "No encontrado"}})
14+
15+
16+
@router.get("/", response_model=list[User])
17+
async def users():
18+
return users_schema(db_client.local.users.find())
19+
20+
21+
@router.get("/{id}") # Path
22+
async def user(id: str):
23+
return search_user("_id", ObjectId(id))
24+
25+
26+
@router.get("/") # Query
27+
async def user(id: str):
28+
return search_user("_id", ObjectId(id))
29+
30+
31+
@router.post("/", response_model=User, status_code=status.HTTP_201_CREATED)
32+
async def user(user: User):
33+
if type(search_user("email", user.email)) == User:
34+
raise HTTPException(
35+
status_code=status.HTTP_404_NOT_FOUND, detail="El usuario ya existe")
36+
37+
user_dict = dict(user)
38+
del user_dict["id"]
39+
40+
id = db_client.local.users.insert_one(user_dict).inserted_id
41+
42+
new_user = user_schema(db_client.local.users.find_one({"_id": id}))
43+
44+
return User(**new_user)
45+
46+
47+
@router.put("/", response_model=User)
48+
async def user(user: User):
49+
50+
user_dict = dict(user)
51+
del user_dict["id"]
52+
53+
try:
54+
db_client.local.users.find_one_and_replace(
55+
{"_id": ObjectId(user.id)}, user_dict)
56+
except:
57+
return {"error": "No se ha actualizado el usuario"}
58+
59+
return search_user("_id", ObjectId(user.id))
60+
61+
62+
@router.delete("/{id}", status_code=status.HTTP_204_NO_CONTENT)
63+
async def user(id: str):
64+
65+
found = db_client.local.users.find_one_and_delete({"_id": ObjectId(id)})
66+
67+
if not found:
68+
return {"error": "No se ha eliminado el usuario"}
69+
70+
# Helper
71+
72+
73+
def search_user(field: str, key):
74+
75+
try:
76+
user = db_client.local.users.find_one({field: key})
77+
return User(**user_schema(user))
78+
except:
79+
return {"error": "No se ha encontrado el usuario"}

README.md

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,9 @@
1212
> ---
1313
> Estoy llevando a cabo un CURSO DESDE CERO gratis para aprender PYTHON en BACKEND.
1414
>
15-
> Veremos temas como:
16-
>
17-
> * API REST
18-
> * CRUD
19-
> * Autenticación
20-
> * Base de datos
21-
> * Despliegue en servidor
22-
>
23-
> **🔴 SIGUIENTE CLASE: Jueves 22 de Diciembre a las 20:00 (hora España)**
15+
> **🔴 SIGUIENTE CLASE: Miércoles 28 de Diciembre a las 20:00 (hora España)**
2416
25-
> 🗓 En [Discord](https://discord.gg/mouredev) tienes creado un [evento](https://discord.gg/mouredev?event=1052999245826883626) para que consultes la hora de tu país y añadas un recordatorio.
17+
> 🗓 En [Discord](https://discord.gg/mouredev) tienes creado un [evento](https://discord.gg/mouredev?event=1055759221637009508) para que consultes la hora de tu país y añadas un recordatorio.
2618
>
2719
> Mientras, aprovecha para practicar unos [retos de programación](https://retosdeprogramacion.com/semanales2022) y así ir mejorando poco a poco.
2820
>
@@ -42,6 +34,7 @@ Curso en el que aprenderemos a utilizar Python para backend e implementaremos un
4234
* [Clase 2 - 01/12/2022 - Operaciones con GET y peticiones HTTP](https://www.twitch.tv/videos/1667582141)
4335
* [Clase 3 - 08/12/2022 - Operaciones con POST, PUT, DELETE, códigos HTTP y Routers](https://www.twitch.tv/videos/1673759045)
4436
* [Clase 4 - 14/12/2022 - Recursos estáticos y Autorización OAuth2](https://www.twitch.tv/videos/1679022882)
37+
* [Clase 5 - 22/12/2022 - Base de datos con MongoDB](https://www.twitch.tv/videos/1686104006)
4538

4639
### Curso de fundamentos desde cero
4740

0 commit comments

Comments
 (0)