Skip to content

Commit

Permalink
Update dependencies (#12)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
jonasrenault authored Nov 1, 2023
1 parent 797f4e0 commit 301f403
Show file tree
Hide file tree
Showing 22 changed files with 3,059 additions and 2,585 deletions.
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ repos:
- id: check-yaml
- id: debug-statements
- repo: https://github.com/psf/black
rev: 23.3.0
rev: 23.10.1
hooks:
- id: black
# It is recommended to specify the latest version of Python
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ The `.env` file that is commited to the github repository contains example value

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

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).
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/).

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).

Expand Down
3 changes: 2 additions & 1 deletion backend/app/config/config.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import secrets
from typing import List
from pydantic import BaseSettings, AnyHttpUrl, EmailStr
from pydantic import AnyHttpUrl, EmailStr
from pydantic_settings import BaseSettings


class Settings(BaseSettings):
Expand Down
51 changes: 32 additions & 19 deletions backend/app/main.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,19 @@
from contextlib import asynccontextmanager

from beanie import init_beanie
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from beanie import init_beanie
from motor.motor_asyncio import AsyncIOMotorClient

from .routers.api import api_router
from .auth.auth import get_hashed_password
from .config.config import settings
from .models.users import User
from .auth.auth import get_hashed_password

app = FastAPI(
title=settings.PROJECT_NAME, openapi_url=f"{settings.API_V1_STR}/openapi.json"
)

# Set all CORS enabled origins
if settings.BACKEND_CORS_ORIGINS:
app.add_middleware(
CORSMiddleware,
allow_origins=[str(origin) for origin in settings.BACKEND_CORS_ORIGINS],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
from .routers.api import api_router


@app.on_event("startup")
async def start_database():
@asynccontextmanager
async def lifespan(app: FastAPI):
# Setup mongoDB
app.client = AsyncIOMotorClient(
settings.MONGO_HOST,
settings.MONGO_PORT,
Expand All @@ -42,5 +31,29 @@ async def start_database():
)
await user.create()

# yield app
yield


app = FastAPI(
title=settings.PROJECT_NAME,
openapi_url=f"{settings.API_V1_STR}/openapi.json",
lifespan=lifespan,
)

# Set all CORS enabled origins
if settings.BACKEND_CORS_ORIGINS:
app.add_middleware(
CORSMiddleware,
allow_origins=[
# See https://github.com/pydantic/pydantic/issues/7186 for reason of using rstrip
str(origin).rstrip("/")
for origin in settings.BACKEND_CORS_ORIGINS
],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)


app.include_router(api_router, prefix=settings.API_V1_STR)
16 changes: 12 additions & 4 deletions backend/app/models/users.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
from typing import Optional
from pydantic import BaseModel, EmailStr, Field
from beanie import Document, Indexed
from datetime import datetime
from uuid import UUID, uuid4

from beanie import Document, Indexed
from pydantic import EmailStr, Field
from pymongo import IndexModel


class User(Document):
uuid: Indexed(UUID, unique=True) = Field(default_factory=uuid4)
uuid: UUID = Field(default_factory=uuid4)
email: Indexed(EmailStr, unique=True)
first_name: Optional[str] = None
last_name: Optional[str] = None
Expand All @@ -15,3 +16,10 @@ class User(Document):
picture: Optional[str] = None
is_active: bool = True
is_superuser: bool = False

class Settings:
# Set unique index on uuid here instead of using Indexed
# because of https://github.com/roman-right/beanie/issues/701
indexes = [
IndexModel("uuid", unique=True),
]
8 changes: 5 additions & 3 deletions backend/app/routers/users.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@ async def update_profile(
"""
Update current user.
"""
update_data = update.dict(exclude={"is_active", "is_superuser"}, exclude_unset=True)
update_data = update.model_dump(
exclude={"is_active", "is_superuser"}, exclude_unset=True
)
try:
if update_data["password"]:
update_data["hashed_password"] = get_hashed_password(
Expand All @@ -79,7 +81,7 @@ async def update_profile(
del update_data["password"]
except KeyError:
pass
current_user = current_user.copy(update=update_data)
current_user = current_user.model_copy(update=update_data)
try:
await current_user.save()
return current_user
Expand Down Expand Up @@ -118,7 +120,7 @@ async def update_user(
user = await models.User.find_one({"uuid": userid})
if update.password is not None:
update.password = get_hashed_password(update.password)
user = user.copy(update=update.dict(exclude_unset=True))
user = user.model_copy(update=update.model_dump(exclude_unset=True))
try:
await user.save()
return user
Expand Down
2 changes: 1 addition & 1 deletion backend/app/schemas/users.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,5 @@ class User(PrivateUserBase):
Should only be returned to admins or self.
"""

id: Optional[PydanticObjectId] = Field(..., alias="_id")
id: PydanticObjectId = Field()
uuid: UUID
Loading

0 comments on commit 301f403

Please sign in to comment.