Skip to content

Commit 301f403

Browse files
authored
Update dependencies (#12)
* Update backend and frontend dependencies. WIP: fix frontend tests and warnings in backend tests * Fix tests: Update msw to latest version and change rest import to http. Remove happy-dom test env as not needed and causing issues * remove deprecated methods due to pydantic v2 * fix build and lint issues * Update Home route with loader to cache values for github repo star counts * Update version to 1.1 * Update version in frontend
1 parent 797f4e0 commit 301f403

22 files changed

+3059
-2585
lines changed

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ repos:
77
- id: check-yaml
88
- id: debug-statements
99
- repo: https://github.com/psf/black
10-
rev: 23.3.0
10+
rev: 23.10.1
1111
hooks:
1212
- id: black
1313
# It is recommended to specify the latest version of Python

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ The `.env` file that is commited to the github repository contains example value
115115

116116
## Setting up Single Sign-On (SSO) with google
117117

118-
To setup SSO and enable the `Sign-In with Google` button, you must first obtain a client-id and secret token from Google. Follow [these steps](https://developers.google.com/identity/protocols/oauth2) to obtain client credentials from your [Google Cloud Console](console.cloud.google.com).
118+
To setup SSO and enable the `Sign-In with Google` button, you must first obtain a client-id and secret token from Google. Follow [these steps](https://developers.google.com/identity/protocols/oauth2) to obtain client credentials from your [Google Cloud Console](https://console.cloud.google.com/).
119119

120120
Create a new project, and from the `APIs & Services` menu, first create an `OAuth consent screen` for you application, then add an `OAuth 2.0 Client Id` in the `Credentials` menu. Select `Web application` as the application type. In the `Authorized redirect URIs`, add your hostname with the `api/v1/login/google/callback` endpoint. For instance, if testing locally while running the backend app with `uvicorn`, add `http://localhost:8000/api/v1/login/google/callback` (use `http://localhost/api/v1/login/google/callback` if running the application in dev with docker). If your application is hosted on a domain name, add it to the list of URIs (remember to update `http` to `https` when using SSL).
121121

backend/app/config/config.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import secrets
22
from typing import List
3-
from pydantic import BaseSettings, AnyHttpUrl, EmailStr
3+
from pydantic import AnyHttpUrl, EmailStr
4+
from pydantic_settings import BaseSettings
45

56

67
class Settings(BaseSettings):

backend/app/main.py

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,19 @@
1+
from contextlib import asynccontextmanager
2+
3+
from beanie import init_beanie
14
from fastapi import FastAPI
25
from fastapi.middleware.cors import CORSMiddleware
3-
from beanie import init_beanie
46
from motor.motor_asyncio import AsyncIOMotorClient
57

6-
from .routers.api import api_router
8+
from .auth.auth import get_hashed_password
79
from .config.config import settings
810
from .models.users import User
9-
from .auth.auth import get_hashed_password
10-
11-
app = FastAPI(
12-
title=settings.PROJECT_NAME, openapi_url=f"{settings.API_V1_STR}/openapi.json"
13-
)
14-
15-
# Set all CORS enabled origins
16-
if settings.BACKEND_CORS_ORIGINS:
17-
app.add_middleware(
18-
CORSMiddleware,
19-
allow_origins=[str(origin) for origin in settings.BACKEND_CORS_ORIGINS],
20-
allow_credentials=True,
21-
allow_methods=["*"],
22-
allow_headers=["*"],
23-
)
11+
from .routers.api import api_router
2412

2513

26-
@app.on_event("startup")
27-
async def start_database():
14+
@asynccontextmanager
15+
async def lifespan(app: FastAPI):
16+
# Setup mongoDB
2817
app.client = AsyncIOMotorClient(
2918
settings.MONGO_HOST,
3019
settings.MONGO_PORT,
@@ -42,5 +31,29 @@ async def start_database():
4231
)
4332
await user.create()
4433

34+
# yield app
35+
yield
36+
37+
38+
app = FastAPI(
39+
title=settings.PROJECT_NAME,
40+
openapi_url=f"{settings.API_V1_STR}/openapi.json",
41+
lifespan=lifespan,
42+
)
43+
44+
# Set all CORS enabled origins
45+
if settings.BACKEND_CORS_ORIGINS:
46+
app.add_middleware(
47+
CORSMiddleware,
48+
allow_origins=[
49+
# See https://github.com/pydantic/pydantic/issues/7186 for reason of using rstrip
50+
str(origin).rstrip("/")
51+
for origin in settings.BACKEND_CORS_ORIGINS
52+
],
53+
allow_credentials=True,
54+
allow_methods=["*"],
55+
allow_headers=["*"],
56+
)
57+
4558

4659
app.include_router(api_router, prefix=settings.API_V1_STR)

backend/app/models/users.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
from typing import Optional
2-
from pydantic import BaseModel, EmailStr, Field
3-
from beanie import Document, Indexed
4-
from datetime import datetime
52
from uuid import UUID, uuid4
63

4+
from beanie import Document, Indexed
5+
from pydantic import EmailStr, Field
6+
from pymongo import IndexModel
7+
78

89
class User(Document):
9-
uuid: Indexed(UUID, unique=True) = Field(default_factory=uuid4)
10+
uuid: UUID = Field(default_factory=uuid4)
1011
email: Indexed(EmailStr, unique=True)
1112
first_name: Optional[str] = None
1213
last_name: Optional[str] = None
@@ -15,3 +16,10 @@ class User(Document):
1516
picture: Optional[str] = None
1617
is_active: bool = True
1718
is_superuser: bool = False
19+
20+
class Settings:
21+
# Set unique index on uuid here instead of using Indexed
22+
# because of https://github.com/roman-right/beanie/issues/701
23+
indexes = [
24+
IndexModel("uuid", unique=True),
25+
]

backend/app/routers/users.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,9 @@ async def update_profile(
7070
"""
7171
Update current user.
7272
"""
73-
update_data = update.dict(exclude={"is_active", "is_superuser"}, exclude_unset=True)
73+
update_data = update.model_dump(
74+
exclude={"is_active", "is_superuser"}, exclude_unset=True
75+
)
7476
try:
7577
if update_data["password"]:
7678
update_data["hashed_password"] = get_hashed_password(
@@ -79,7 +81,7 @@ async def update_profile(
7981
del update_data["password"]
8082
except KeyError:
8183
pass
82-
current_user = current_user.copy(update=update_data)
84+
current_user = current_user.model_copy(update=update_data)
8385
try:
8486
await current_user.save()
8587
return current_user
@@ -118,7 +120,7 @@ async def update_user(
118120
user = await models.User.find_one({"uuid": userid})
119121
if update.password is not None:
120122
update.password = get_hashed_password(update.password)
121-
user = user.copy(update=update.dict(exclude_unset=True))
123+
user = user.model_copy(update=update.model_dump(exclude_unset=True))
122124
try:
123125
await user.save()
124126
return user

backend/app/schemas/users.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,5 +44,5 @@ class User(PrivateUserBase):
4444
Should only be returned to admins or self.
4545
"""
4646

47-
id: Optional[PydanticObjectId] = Field(..., alias="_id")
47+
id: PydanticObjectId = Field()
4848
uuid: UUID

0 commit comments

Comments
 (0)