Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions {{cookiecutter.project_slug}}/backend/app/.flake8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
[flake8]
max-line-length = 88
exclude = .git,__pycache__,__init__.py,.mypy_cache,.pytest_cache
3 changes: 3 additions & 0 deletions {{cookiecutter.project_slug}}/backend/app/.gitignore
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
.mypy_cache
.coverage
htmlcov
Original file line numberDiff line numberDiff line change
@@ -1,104 +1,99 @@
from typing import List
from typing import Any, List

from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session

from app import crud
from app.api.utils.db import get_db
from app.api.utils.security import get_current_active_user
from app.models.user import User as DBUser
from app.schemas.item import Item, ItemCreate, ItemUpdate
from app import crud, models, schemas
from app.api import deps

router = APIRouter()


@router.get("/", response_model=List[Item])
@router.get("/", response_model=List[schemas.Item])
def read_items(
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
skip: int = 0,
limit: int = 100,
current_user: DBUser = Depends(get_current_active_user),
):
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Retrieve items.
"""
if crud.user.is_superuser(current_user):
items = crud.item.get_multi(db, skip=skip, limit=limit)
else:
items = crud.item.get_multi_by_owner(
db_session=db, owner_id=current_user.id, skip=skip, limit=limit
db=db, owner_id=current_user.id, skip=skip, limit=limit
)
return items


@router.post("/", response_model=Item)
@router.post("/", response_model=schemas.Item)
def create_item(
*,
db: Session = Depends(get_db),
item_in: ItemCreate,
current_user: DBUser = Depends(get_current_active_user),
):
db: Session = Depends(deps.get_db),
item_in: schemas.ItemCreate,
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Create new item.
"""
item = crud.item.create_with_owner(
db_session=db, obj_in=item_in, owner_id=current_user.id
)
item = crud.item.create_with_owner(db=db, obj_in=item_in, owner_id=current_user.id)
return item


@router.put("/{id}", response_model=Item)
@router.put("/{id}", response_model=schemas.Item)
def update_item(
*,
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
id: int,
item_in: ItemUpdate,
current_user: DBUser = Depends(get_current_active_user),
):
item_in: schemas.ItemUpdate,
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Update an item.
"""
item = crud.item.get(db_session=db, id=id)
item = crud.item.get(db=db, id=id)
if not item:
raise HTTPException(status_code=404, detail="Item not found")
if not crud.user.is_superuser(current_user) and (item.owner_id != current_user.id):
raise HTTPException(status_code=400, detail="Not enough permissions")
item = crud.item.update(db_session=db, db_obj=item, obj_in=item_in)
item = crud.item.update(db=db, db_obj=item, obj_in=item_in)
return item


@router.get("/{id}", response_model=Item)
@router.get("/{id}", response_model=schemas.Item)
def read_item(
*,
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
id: int,
current_user: DBUser = Depends(get_current_active_user),
):
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Get item by ID.
"""
item = crud.item.get(db_session=db, id=id)
item = crud.item.get(db=db, id=id)
if not item:
raise HTTPException(status_code=404, detail="Item not found")
if not crud.user.is_superuser(current_user) and (item.owner_id != current_user.id):
raise HTTPException(status_code=400, detail="Not enough permissions")
return item


@router.delete("/{id}", response_model=Item)
@router.delete("/{id}", response_model=schemas.Item)
def delete_item(
*,
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
id: int,
current_user: DBUser = Depends(get_current_active_user),
):
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Delete an item.
"""
item = crud.item.get(db_session=db, id=id)
item = crud.item.get(db=db, id=id)
if not item:
raise HTTPException(status_code=404, detail="Item not found")
if not crud.user.is_superuser(current_user) and (item.owner_id != current_user.id):
raise HTTPException(status_code=400, detail="Not enough permissions")
item = crud.item.remove(db_session=db, id=id)
item = crud.item.remove(db=db, id=id)
return item
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,15 @@
from datetime import timedelta
from typing import Any

from fastapi import APIRouter, Body, Depends, HTTPException
from fastapi.security import OAuth2PasswordRequestForm
from sqlalchemy.orm import Session

from app import crud
from app.api.utils.db import get_db
from app.api.utils.security import get_current_user
from app import crud, models, schemas
from app.api import deps
from app.core import security
from app.core.config import settings
from app.core.jwt import create_access_token
from app.core.security import get_password_hash
from app.models.user import User as DBUser
from app.schemas.msg import Msg
from app.schemas.token import Token
from app.schemas.user import User
from app.utils import (
generate_password_reset_token,
send_reset_password_email,
Expand All@@ -23,10 +19,10 @@
router = APIRouter()


@router.post("/login/access-token", response_model=Token)
@router.post("/login/access-token", response_model=schemas.Token)
def login_access_token(
db: Session = Depends(get_db), form_data: OAuth2PasswordRequestForm = Depends()
):
db: Session = Depends(deps.get_db), form_data: OAuth2PasswordRequestForm = Depends()
) -> Any:
"""
OAuth2 compatible token login, get an access token for future requests
"""
Expand All@@ -39,23 +35,23 @@ def login_access_token(
raise HTTPException(status_code=400, detail="Inactive user")
access_token_expires = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
return {
"access_token": create_access_token(
data={"user_id": user.id}, expires_delta=access_token_expires
"access_token": security.create_access_token(
user.id, expires_delta=access_token_expires
),
"token_type": "bearer",
}


@router.post("/login/test-token", response_model=User)
def test_token(current_user: DBUser = Depends(get_current_user)):
@router.post("/login/test-token", response_model=schemas.User)
def test_token(current_user: models.User = Depends(deps.get_current_user)) -> Any:
"""
Test access token
"""
return current_user


@router.post("/password-recovery/{email}", response_model=Msg)
def recover_password(email: str, db: Session = Depends(get_db)):
@router.post("/password-recovery/{email}", response_model=schemas.Msg)
def recover_password(email: str, db: Session = Depends(deps.get_db)) -> Any:
"""
Password Recovery
"""
Expand All@@ -73,10 +69,12 @@ def recover_password(email: str, db: Session = Depends(get_db)):
return {"msg": "Password recovery email sent"}


@router.post("/reset-password/", response_model=Msg)
@router.post("/reset-password/", response_model=schemas.Msg)
def reset_password(
token: str = Body(...), new_password: str = Body(...), db: Session = Depends(get_db)
):
token: str = Body(...),
new_password: str = Body(...),
db: Session = Depends(deps.get_db),
) -> Any:
"""
Reset password
"""
Expand Down
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,39 @@
from typing import List
from typing import Any, List

from fastapi import APIRouter, Body, Depends, HTTPException
from fastapi.encoders import jsonable_encoder
from pydantic.networks import EmailStr
from sqlalchemy.orm import Session

from app import crud
from app.api.utils.db import get_db
from app.api.utils.security import get_current_active_superuser, get_current_active_user
from app import crud, models, schemas
from app.api import deps
from app.core.config import settings
from app.models.user import User as DBUser
from app.schemas.user import User, UserCreate, UserUpdate
from app.utils import send_new_account_email

router = APIRouter()


@router.get("/", response_model=List[User])
@router.get("/", response_model=List[schemas.User])
def read_users(
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
skip: int = 0,
limit: int = 100,
current_user: DBUser = Depends(get_current_active_superuser),
):
current_user: models.User = Depends(deps.get_current_active_superuser),
) -> Any:
"""
Retrieve users.
"""
users = crud.user.get_multi(db, skip=skip, limit=limit)
return users


@router.post("/", response_model=User)
@router.post("/", response_model=schemas.User)
def create_user(
*,
db: Session = Depends(get_db),
user_in: UserCreate,
current_user: DBUser = Depends(get_current_active_superuser),
):
db: Session = Depends(deps.get_db),
user_in: schemas.UserCreate,
current_user: models.User = Depends(deps.get_current_active_superuser),
) -> Any:
"""
Create new user.
"""
Expand All@@ -54,20 +51,20 @@ def create_user(
return user


@router.put("/me", response_model=User)
@router.put("/me", response_model=schemas.User)
def update_user_me(
*,
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
password: str = Body(None),
full_name: str = Body(None),
email: EmailStr = Body(None),
current_user: DBUser = Depends(get_current_active_user),
):
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Update own user.
"""
current_user_data = jsonable_encoder(current_user)
user_in = UserUpdate(**current_user_data)
user_in = schemas.UserUpdate(**current_user_data)
if password is not None:
user_in.password = password
if full_name is not None:
Expand All@@ -78,25 +75,25 @@ def update_user_me(
return user


@router.get("/me", response_model=User)
@router.get("/me", response_model=schemas.User)
def read_user_me(
db: Session = Depends(get_db),
current_user: DBUser = Depends(get_current_active_user),
):
db: Session = Depends(deps.get_db),
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Get current user.
"""
return current_user


@router.post("/open", response_model=User)
@router.post("/open", response_model=schemas.User)
def create_user_open(
*,
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
password: str = Body(...),
email: EmailStr = Body(...),
full_name: str = Body(None),
):
) -> Any:
"""
Create new user without the need to be logged in.
"""
Expand All@@ -111,17 +108,17 @@ def create_user_open(
status_code=400,
detail="The user with this username already exists in the system",
)
user_in = UserCreate(password=password, email=email, full_name=full_name)
user_in = schemas.UserCreate(password=password, email=email, full_name=full_name)
user = crud.user.create(db, obj_in=user_in)
return user


@router.get("/{user_id}", response_model=User)
@router.get("/{user_id}", response_model=schemas.User)
def read_user_by_id(
user_id: int,
current_user: DBUser = Depends(get_current_active_user),
db: Session = Depends(get_db),
):
current_user: models.User = Depends(deps.get_current_active_user),
db: Session = Depends(deps.get_db),
) -> Any:
"""
Get a specific user by id.
"""
Expand All@@ -135,14 +132,14 @@ def read_user_by_id(
return user


@router.put("/{user_id}", response_model=User)
@router.put("/{user_id}", response_model=schemas.User)
def update_user(
*,
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
user_id: int,
user_in: UserUpdate,
current_user: DBUser = Depends(get_current_active_superuser),
):
user_in: schemas.UserUpdate,
current_user: models.User = Depends(deps.get_current_active_superuser),
) -> Any:
"""
Update a user.
"""
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions {{cookiecutter.project_slug}}/backend/app/.flake8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
[flake8]
max-line-length = 88
exclude = .git,__pycache__,__init__.py,.mypy_cache,.pytest_cache
3 changes: 3 additions & 0 deletions {{cookiecutter.project_slug}}/backend/app/.gitignore
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
.mypy_cache
.coverage
htmlcov
Original file line numberDiff line numberDiff line change
@@ -1,104 +1,99 @@
from typing import List
from typing import Any, List

from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session

from app import crud
from app.api.utils.db import get_db
from app.api.utils.security import get_current_active_user
from app.models.user import User as DBUser
from app.schemas.item import Item, ItemCreate, ItemUpdate
from app import crud, models, schemas
from app.api import deps

router = APIRouter()


@router.get("/", response_model=List[Item])
@router.get("/", response_model=List[schemas.Item])
def read_items(
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
skip: int = 0,
limit: int = 100,
current_user: DBUser = Depends(get_current_active_user),
):
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Retrieve items.
"""
if crud.user.is_superuser(current_user):
items = crud.item.get_multi(db, skip=skip, limit=limit)
else:
items = crud.item.get_multi_by_owner(
db_session=db, owner_id=current_user.id, skip=skip, limit=limit
db=db, owner_id=current_user.id, skip=skip, limit=limit
)
return items


@router.post("/", response_model=Item)
@router.post("/", response_model=schemas.Item)
def create_item(
*,
db: Session = Depends(get_db),
item_in: ItemCreate,
current_user: DBUser = Depends(get_current_active_user),
):
db: Session = Depends(deps.get_db),
item_in: schemas.ItemCreate,
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Create new item.
"""
item = crud.item.create_with_owner(
db_session=db, obj_in=item_in, owner_id=current_user.id
)
item = crud.item.create_with_owner(db=db, obj_in=item_in, owner_id=current_user.id)
return item


@router.put("/{id}", response_model=Item)
@router.put("/{id}", response_model=schemas.Item)
def update_item(
*,
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
id: int,
item_in: ItemUpdate,
current_user: DBUser = Depends(get_current_active_user),
):
item_in: schemas.ItemUpdate,
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Update an item.
"""
item = crud.item.get(db_session=db, id=id)
item = crud.item.get(db=db, id=id)
if not item:
raise HTTPException(status_code=404, detail="Item not found")
if not crud.user.is_superuser(current_user) and (item.owner_id != current_user.id):
raise HTTPException(status_code=400, detail="Not enough permissions")
item = crud.item.update(db_session=db, db_obj=item, obj_in=item_in)
item = crud.item.update(db=db, db_obj=item, obj_in=item_in)
return item


@router.get("/{id}", response_model=Item)
@router.get("/{id}", response_model=schemas.Item)
def read_item(
*,
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
id: int,
current_user: DBUser = Depends(get_current_active_user),
):
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Get item by ID.
"""
item = crud.item.get(db_session=db, id=id)
item = crud.item.get(db=db, id=id)
if not item:
raise HTTPException(status_code=404, detail="Item not found")
if not crud.user.is_superuser(current_user) and (item.owner_id != current_user.id):
raise HTTPException(status_code=400, detail="Not enough permissions")
return item


@router.delete("/{id}", response_model=Item)
@router.delete("/{id}", response_model=schemas.Item)
def delete_item(
*,
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
id: int,
current_user: DBUser = Depends(get_current_active_user),
):
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Delete an item.
"""
item = crud.item.get(db_session=db, id=id)
item = crud.item.get(db=db, id=id)
if not item:
raise HTTPException(status_code=404, detail="Item not found")
if not crud.user.is_superuser(current_user) and (item.owner_id != current_user.id):
raise HTTPException(status_code=400, detail="Not enough permissions")
item = crud.item.remove(db_session=db, id=id)
item = crud.item.remove(db=db, id=id)
return item
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,15 @@
from datetime import timedelta
from typing import Any

from fastapi import APIRouter, Body, Depends, HTTPException
from fastapi.security import OAuth2PasswordRequestForm
from sqlalchemy.orm import Session

from app import crud
from app.api.utils.db import get_db
from app.api.utils.security import get_current_user
from app import crud, models, schemas
from app.api import deps
from app.core import security
from app.core.config import settings
from app.core.jwt import create_access_token
from app.core.security import get_password_hash
from app.models.user import User as DBUser
from app.schemas.msg import Msg
from app.schemas.token import Token
from app.schemas.user import User
from app.utils import (
generate_password_reset_token,
send_reset_password_email,
Expand All@@ -23,10 +19,10 @@
router = APIRouter()


@router.post("/login/access-token", response_model=Token)
@router.post("/login/access-token", response_model=schemas.Token)
def login_access_token(
db: Session = Depends(get_db), form_data: OAuth2PasswordRequestForm = Depends()
):
db: Session = Depends(deps.get_db), form_data: OAuth2PasswordRequestForm = Depends()
) -> Any:
"""
OAuth2 compatible token login, get an access token for future requests
"""
Expand All@@ -39,23 +35,23 @@ def login_access_token(
raise HTTPException(status_code=400, detail="Inactive user")
access_token_expires = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
return {
"access_token": create_access_token(
data={"user_id": user.id}, expires_delta=access_token_expires
"access_token": security.create_access_token(
user.id, expires_delta=access_token_expires
),
"token_type": "bearer",
}


@router.post("/login/test-token", response_model=User)
def test_token(current_user: DBUser = Depends(get_current_user)):
@router.post("/login/test-token", response_model=schemas.User)
def test_token(current_user: models.User = Depends(deps.get_current_user)) -> Any:
"""
Test access token
"""
return current_user


@router.post("/password-recovery/{email}", response_model=Msg)
def recover_password(email: str, db: Session = Depends(get_db)):
@router.post("/password-recovery/{email}", response_model=schemas.Msg)
def recover_password(email: str, db: Session = Depends(deps.get_db)) -> Any:
"""
Password Recovery
"""
Expand All@@ -73,10 +69,12 @@ def recover_password(email: str, db: Session = Depends(get_db)):
return {"msg": "Password recovery email sent"}


@router.post("/reset-password/", response_model=Msg)
@router.post("/reset-password/", response_model=schemas.Msg)
def reset_password(
token: str = Body(...), new_password: str = Body(...), db: Session = Depends(get_db)
):
token: str = Body(...),
new_password: str = Body(...),
db: Session = Depends(deps.get_db),
) -> Any:
"""
Reset password
"""
Expand Down
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,39 @@
from typing import List
from typing import Any, List

from fastapi import APIRouter, Body, Depends, HTTPException
from fastapi.encoders import jsonable_encoder
from pydantic.networks import EmailStr
from sqlalchemy.orm import Session

from app import crud
from app.api.utils.db import get_db
from app.api.utils.security import get_current_active_superuser, get_current_active_user
from app import crud, models, schemas
from app.api import deps
from app.core.config import settings
from app.models.user import User as DBUser
from app.schemas.user import User, UserCreate, UserUpdate
from app.utils import send_new_account_email

router = APIRouter()


@router.get("/", response_model=List[User])
@router.get("/", response_model=List[schemas.User])
def read_users(
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
skip: int = 0,
limit: int = 100,
current_user: DBUser = Depends(get_current_active_superuser),
):
current_user: models.User = Depends(deps.get_current_active_superuser),
) -> Any:
"""
Retrieve users.
"""
users = crud.user.get_multi(db, skip=skip, limit=limit)
return users


@router.post("/", response_model=User)
@router.post("/", response_model=schemas.User)
def create_user(
*,
db: Session = Depends(get_db),
user_in: UserCreate,
current_user: DBUser = Depends(get_current_active_superuser),
):
db: Session = Depends(deps.get_db),
user_in: schemas.UserCreate,
current_user: models.User = Depends(deps.get_current_active_superuser),
) -> Any:
"""
Create new user.
"""
Expand All@@ -54,20 +51,20 @@ def create_user(
return user


@router.put("/me", response_model=User)
@router.put("/me", response_model=schemas.User)
def update_user_me(
*,
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
password: str = Body(None),
full_name: str = Body(None),
email: EmailStr = Body(None),
current_user: DBUser = Depends(get_current_active_user),
):
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Update own user.
"""
current_user_data = jsonable_encoder(current_user)
user_in = UserUpdate(**current_user_data)
user_in = schemas.UserUpdate(**current_user_data)
if password is not None:
user_in.password = password
if full_name is not None:
Expand All@@ -78,25 +75,25 @@ def update_user_me(
return user


@router.get("/me", response_model=User)
@router.get("/me", response_model=schemas.User)
def read_user_me(
db: Session = Depends(get_db),
current_user: DBUser = Depends(get_current_active_user),
):
db: Session = Depends(deps.get_db),
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Get current user.
"""
return current_user


@router.post("/open", response_model=User)
@router.post("/open", response_model=schemas.User)
def create_user_open(
*,
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
password: str = Body(...),
email: EmailStr = Body(...),
full_name: str = Body(None),
):
) -> Any:
"""
Create new user without the need to be logged in.
"""
Expand All@@ -111,17 +108,17 @@ def create_user_open(
status_code=400,
detail="The user with this username already exists in the system",
)
user_in = UserCreate(password=password, email=email, full_name=full_name)
user_in = schemas.UserCreate(password=password, email=email, full_name=full_name)
user = crud.user.create(db, obj_in=user_in)
return user


@router.get("/{user_id}", response_model=User)
@router.get("/{user_id}", response_model=schemas.User)
def read_user_by_id(
user_id: int,
current_user: DBUser = Depends(get_current_active_user),
db: Session = Depends(get_db),
):
current_user: models.User = Depends(deps.get_current_active_user),
db: Session = Depends(deps.get_db),
) -> Any:
"""
Get a specific user by id.
"""
Expand All@@ -135,14 +132,14 @@ def read_user_by_id(
return user


@router.put("/{user_id}", response_model=User)
@router.put("/{user_id}", response_model=schemas.User)
def update_user(
*,
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
user_id: int,
user_in: UserUpdate,
current_user: DBUser = Depends(get_current_active_superuser),
):
user_in: schemas.UserUpdate,
current_user: models.User = Depends(deps.get_current_active_superuser),
) -> Any:
"""
Update a user.
"""
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions {{cookiecutter.project_slug}}/backend/app/.flake8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
[flake8]
max-line-length = 88
exclude = .git,__pycache__,__init__.py,.mypy_cache,.pytest_cache
3 changes: 3 additions & 0 deletions {{cookiecutter.project_slug}}/backend/app/.gitignore
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
.mypy_cache
.coverage
htmlcov
Original file line numberDiff line numberDiff line change
@@ -1,104 +1,99 @@
from typing import List
from typing import Any, List

from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session

from app import crud
from app.api.utils.db import get_db
from app.api.utils.security import get_current_active_user
from app.models.user import User as DBUser
from app.schemas.item import Item, ItemCreate, ItemUpdate
from app import crud, models, schemas
from app.api import deps

router = APIRouter()


@router.get("/", response_model=List[Item])
@router.get("/", response_model=List[schemas.Item])
def read_items(
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
skip: int = 0,
limit: int = 100,
current_user: DBUser = Depends(get_current_active_user),
):
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Retrieve items.
"""
if crud.user.is_superuser(current_user):
items = crud.item.get_multi(db, skip=skip, limit=limit)
else:
items = crud.item.get_multi_by_owner(
db_session=db, owner_id=current_user.id, skip=skip, limit=limit
db=db, owner_id=current_user.id, skip=skip, limit=limit
)
return items


@router.post("/", response_model=Item)
@router.post("/", response_model=schemas.Item)
def create_item(
*,
db: Session = Depends(get_db),
item_in: ItemCreate,
current_user: DBUser = Depends(get_current_active_user),
):
db: Session = Depends(deps.get_db),
item_in: schemas.ItemCreate,
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Create new item.
"""
item = crud.item.create_with_owner(
db_session=db, obj_in=item_in, owner_id=current_user.id
)
item = crud.item.create_with_owner(db=db, obj_in=item_in, owner_id=current_user.id)
return item


@router.put("/{id}", response_model=Item)
@router.put("/{id}", response_model=schemas.Item)
def update_item(
*,
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
id: int,
item_in: ItemUpdate,
current_user: DBUser = Depends(get_current_active_user),
):
item_in: schemas.ItemUpdate,
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Update an item.
"""
item = crud.item.get(db_session=db, id=id)
item = crud.item.get(db=db, id=id)
if not item:
raise HTTPException(status_code=404, detail="Item not found")
if not crud.user.is_superuser(current_user) and (item.owner_id != current_user.id):
raise HTTPException(status_code=400, detail="Not enough permissions")
item = crud.item.update(db_session=db, db_obj=item, obj_in=item_in)
item = crud.item.update(db=db, db_obj=item, obj_in=item_in)
return item


@router.get("/{id}", response_model=Item)
@router.get("/{id}", response_model=schemas.Item)
def read_item(
*,
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
id: int,
current_user: DBUser = Depends(get_current_active_user),
):
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Get item by ID.
"""
item = crud.item.get(db_session=db, id=id)
item = crud.item.get(db=db, id=id)
if not item:
raise HTTPException(status_code=404, detail="Item not found")
if not crud.user.is_superuser(current_user) and (item.owner_id != current_user.id):
raise HTTPException(status_code=400, detail="Not enough permissions")
return item


@router.delete("/{id}", response_model=Item)
@router.delete("/{id}", response_model=schemas.Item)
def delete_item(
*,
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
id: int,
current_user: DBUser = Depends(get_current_active_user),
):
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Delete an item.
"""
item = crud.item.get(db_session=db, id=id)
item = crud.item.get(db=db, id=id)
if not item:
raise HTTPException(status_code=404, detail="Item not found")
if not crud.user.is_superuser(current_user) and (item.owner_id != current_user.id):
raise HTTPException(status_code=400, detail="Not enough permissions")
item = crud.item.remove(db_session=db, id=id)
item = crud.item.remove(db=db, id=id)
return item
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,15 @@
from datetime import timedelta
from typing import Any

from fastapi import APIRouter, Body, Depends, HTTPException
from fastapi.security import OAuth2PasswordRequestForm
from sqlalchemy.orm import Session

from app import crud
from app.api.utils.db import get_db
from app.api.utils.security import get_current_user
from app import crud, models, schemas
from app.api import deps
from app.core import security
from app.core.config import settings
from app.core.jwt import create_access_token
from app.core.security import get_password_hash
from app.models.user import User as DBUser
from app.schemas.msg import Msg
from app.schemas.token import Token
from app.schemas.user import User
from app.utils import (
generate_password_reset_token,
send_reset_password_email,
Expand All@@ -23,10 +19,10 @@
router = APIRouter()


@router.post("/login/access-token", response_model=Token)
@router.post("/login/access-token", response_model=schemas.Token)
def login_access_token(
db: Session = Depends(get_db), form_data: OAuth2PasswordRequestForm = Depends()
):
db: Session = Depends(deps.get_db), form_data: OAuth2PasswordRequestForm = Depends()
) -> Any:
"""
OAuth2 compatible token login, get an access token for future requests
"""
Expand All@@ -39,23 +35,23 @@ def login_access_token(
raise HTTPException(status_code=400, detail="Inactive user")
access_token_expires = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
return {
"access_token": create_access_token(
data={"user_id": user.id}, expires_delta=access_token_expires
"access_token": security.create_access_token(
user.id, expires_delta=access_token_expires
),
"token_type": "bearer",
}


@router.post("/login/test-token", response_model=User)
def test_token(current_user: DBUser = Depends(get_current_user)):
@router.post("/login/test-token", response_model=schemas.User)
def test_token(current_user: models.User = Depends(deps.get_current_user)) -> Any:
"""
Test access token
"""
return current_user


@router.post("/password-recovery/{email}", response_model=Msg)
def recover_password(email: str, db: Session = Depends(get_db)):
@router.post("/password-recovery/{email}", response_model=schemas.Msg)
def recover_password(email: str, db: Session = Depends(deps.get_db)) -> Any:
"""
Password Recovery
"""
Expand All@@ -73,10 +69,12 @@ def recover_password(email: str, db: Session = Depends(get_db)):
return {"msg": "Password recovery email sent"}


@router.post("/reset-password/", response_model=Msg)
@router.post("/reset-password/", response_model=schemas.Msg)
def reset_password(
token: str = Body(...), new_password: str = Body(...), db: Session = Depends(get_db)
):
token: str = Body(...),
new_password: str = Body(...),
db: Session = Depends(deps.get_db),
) -> Any:
"""
Reset password
"""
Expand Down
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,39 @@
from typing import List
from typing import Any, List

from fastapi import APIRouter, Body, Depends, HTTPException
from fastapi.encoders import jsonable_encoder
from pydantic.networks import EmailStr
from sqlalchemy.orm import Session

from app import crud
from app.api.utils.db import get_db
from app.api.utils.security import get_current_active_superuser, get_current_active_user
from app import crud, models, schemas
from app.api import deps
from app.core.config import settings
from app.models.user import User as DBUser
from app.schemas.user import User, UserCreate, UserUpdate
from app.utils import send_new_account_email

router = APIRouter()


@router.get("/", response_model=List[User])
@router.get("/", response_model=List[schemas.User])
def read_users(
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
skip: int = 0,
limit: int = 100,
current_user: DBUser = Depends(get_current_active_superuser),
):
current_user: models.User = Depends(deps.get_current_active_superuser),
) -> Any:
"""
Retrieve users.
"""
users = crud.user.get_multi(db, skip=skip, limit=limit)
return users


@router.post("/", response_model=User)
@router.post("/", response_model=schemas.User)
def create_user(
*,
db: Session = Depends(get_db),
user_in: UserCreate,
current_user: DBUser = Depends(get_current_active_superuser),
):
db: Session = Depends(deps.get_db),
user_in: schemas.UserCreate,
current_user: models.User = Depends(deps.get_current_active_superuser),
) -> Any:
"""
Create new user.
"""
Expand All@@ -54,20 +51,20 @@ def create_user(
return user


@router.put("/me", response_model=User)
@router.put("/me", response_model=schemas.User)
def update_user_me(
*,
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
password: str = Body(None),
full_name: str = Body(None),
email: EmailStr = Body(None),
current_user: DBUser = Depends(get_current_active_user),
):
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Update own user.
"""
current_user_data = jsonable_encoder(current_user)
user_in = UserUpdate(**current_user_data)
user_in = schemas.UserUpdate(**current_user_data)
if password is not None:
user_in.password = password
if full_name is not None:
Expand All@@ -78,25 +75,25 @@ def update_user_me(
return user


@router.get("/me", response_model=User)
@router.get("/me", response_model=schemas.User)
def read_user_me(
db: Session = Depends(get_db),
current_user: DBUser = Depends(get_current_active_user),
):
db: Session = Depends(deps.get_db),
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Get current user.
"""
return current_user


@router.post("/open", response_model=User)
@router.post("/open", response_model=schemas.User)
def create_user_open(
*,
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
password: str = Body(...),
email: EmailStr = Body(...),
full_name: str = Body(None),
):
) -> Any:
"""
Create new user without the need to be logged in.
"""
Expand All@@ -111,17 +108,17 @@ def create_user_open(
status_code=400,
detail="The user with this username already exists in the system",
)
user_in = UserCreate(password=password, email=email, full_name=full_name)
user_in = schemas.UserCreate(password=password, email=email, full_name=full_name)
user = crud.user.create(db, obj_in=user_in)
return user


@router.get("/{user_id}", response_model=User)
@router.get("/{user_id}", response_model=schemas.User)
def read_user_by_id(
user_id: int,
current_user: DBUser = Depends(get_current_active_user),
db: Session = Depends(get_db),
):
current_user: models.User = Depends(deps.get_current_active_user),
db: Session = Depends(deps.get_db),
) -> Any:
"""
Get a specific user by id.
"""
Expand All@@ -135,14 +132,14 @@ def read_user_by_id(
return user


@router.put("/{user_id}", response_model=User)
@router.put("/{user_id}", response_model=schemas.User)
def update_user(
*,
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
user_id: int,
user_in: UserUpdate,
current_user: DBUser = Depends(get_current_active_superuser),
):
user_in: schemas.UserUpdate,
current_user: models.User = Depends(deps.get_current_active_superuser),
) -> Any:
"""
Update a user.
"""
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions {{cookiecutter.project_slug}}/backend/app/.flake8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
[flake8]
max-line-length = 88
exclude = .git,__pycache__,__init__.py,.mypy_cache,.pytest_cache
3 changes: 3 additions & 0 deletions {{cookiecutter.project_slug}}/backend/app/.gitignore
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
.mypy_cache
.coverage
htmlcov
Original file line numberDiff line numberDiff line change
@@ -1,104 +1,99 @@
from typing import List
from typing import Any, List

from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session

from app import crud
from app.api.utils.db import get_db
from app.api.utils.security import get_current_active_user
from app.models.user import User as DBUser
from app.schemas.item import Item, ItemCreate, ItemUpdate
from app import crud, models, schemas
from app.api import deps

router = APIRouter()


@router.get("/", response_model=List[Item])
@router.get("/", response_model=List[schemas.Item])
def read_items(
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
skip: int = 0,
limit: int = 100,
current_user: DBUser = Depends(get_current_active_user),
):
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Retrieve items.
"""
if crud.user.is_superuser(current_user):
items = crud.item.get_multi(db, skip=skip, limit=limit)
else:
items = crud.item.get_multi_by_owner(
db_session=db, owner_id=current_user.id, skip=skip, limit=limit
db=db, owner_id=current_user.id, skip=skip, limit=limit
)
return items


@router.post("/", response_model=Item)
@router.post("/", response_model=schemas.Item)
def create_item(
*,
db: Session = Depends(get_db),
item_in: ItemCreate,
current_user: DBUser = Depends(get_current_active_user),
):
db: Session = Depends(deps.get_db),
item_in: schemas.ItemCreate,
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Create new item.
"""
item = crud.item.create_with_owner(
db_session=db, obj_in=item_in, owner_id=current_user.id
)
item = crud.item.create_with_owner(db=db, obj_in=item_in, owner_id=current_user.id)
return item


@router.put("/{id}", response_model=Item)
@router.put("/{id}", response_model=schemas.Item)
def update_item(
*,
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
id: int,
item_in: ItemUpdate,
current_user: DBUser = Depends(get_current_active_user),
):
item_in: schemas.ItemUpdate,
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Update an item.
"""
item = crud.item.get(db_session=db, id=id)
item = crud.item.get(db=db, id=id)
if not item:
raise HTTPException(status_code=404, detail="Item not found")
if not crud.user.is_superuser(current_user) and (item.owner_id != current_user.id):
raise HTTPException(status_code=400, detail="Not enough permissions")
item = crud.item.update(db_session=db, db_obj=item, obj_in=item_in)
item = crud.item.update(db=db, db_obj=item, obj_in=item_in)
return item


@router.get("/{id}", response_model=Item)
@router.get("/{id}", response_model=schemas.Item)
def read_item(
*,
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
id: int,
current_user: DBUser = Depends(get_current_active_user),
):
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Get item by ID.
"""
item = crud.item.get(db_session=db, id=id)
item = crud.item.get(db=db, id=id)
if not item:
raise HTTPException(status_code=404, detail="Item not found")
if not crud.user.is_superuser(current_user) and (item.owner_id != current_user.id):
raise HTTPException(status_code=400, detail="Not enough permissions")
return item


@router.delete("/{id}", response_model=Item)
@router.delete("/{id}", response_model=schemas.Item)
def delete_item(
*,
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
id: int,
current_user: DBUser = Depends(get_current_active_user),
):
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Delete an item.
"""
item = crud.item.get(db_session=db, id=id)
item = crud.item.get(db=db, id=id)
if not item:
raise HTTPException(status_code=404, detail="Item not found")
if not crud.user.is_superuser(current_user) and (item.owner_id != current_user.id):
raise HTTPException(status_code=400, detail="Not enough permissions")
item = crud.item.remove(db_session=db, id=id)
item = crud.item.remove(db=db, id=id)
return item
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,15 @@
from datetime import timedelta
from typing import Any

from fastapi import APIRouter, Body, Depends, HTTPException
from fastapi.security import OAuth2PasswordRequestForm
from sqlalchemy.orm import Session

from app import crud
from app.api.utils.db import get_db
from app.api.utils.security import get_current_user
from app import crud, models, schemas
from app.api import deps
from app.core import security
from app.core.config import settings
from app.core.jwt import create_access_token
from app.core.security import get_password_hash
from app.models.user import User as DBUser
from app.schemas.msg import Msg
from app.schemas.token import Token
from app.schemas.user import User
from app.utils import (
generate_password_reset_token,
send_reset_password_email,
Expand All@@ -23,10 +19,10 @@
router = APIRouter()


@router.post("/login/access-token", response_model=Token)
@router.post("/login/access-token", response_model=schemas.Token)
def login_access_token(
db: Session = Depends(get_db), form_data: OAuth2PasswordRequestForm = Depends()
):
db: Session = Depends(deps.get_db), form_data: OAuth2PasswordRequestForm = Depends()
) -> Any:
"""
OAuth2 compatible token login, get an access token for future requests
"""
Expand All@@ -39,23 +35,23 @@ def login_access_token(
raise HTTPException(status_code=400, detail="Inactive user")
access_token_expires = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
return {
"access_token": create_access_token(
data={"user_id": user.id}, expires_delta=access_token_expires
"access_token": security.create_access_token(
user.id, expires_delta=access_token_expires
),
"token_type": "bearer",
}


@router.post("/login/test-token", response_model=User)
def test_token(current_user: DBUser = Depends(get_current_user)):
@router.post("/login/test-token", response_model=schemas.User)
def test_token(current_user: models.User = Depends(deps.get_current_user)) -> Any:
"""
Test access token
"""
return current_user


@router.post("/password-recovery/{email}", response_model=Msg)
def recover_password(email: str, db: Session = Depends(get_db)):
@router.post("/password-recovery/{email}", response_model=schemas.Msg)
def recover_password(email: str, db: Session = Depends(deps.get_db)) -> Any:
"""
Password Recovery
"""
Expand All@@ -73,10 +69,12 @@ def recover_password(email: str, db: Session = Depends(get_db)):
return {"msg": "Password recovery email sent"}


@router.post("/reset-password/", response_model=Msg)
@router.post("/reset-password/", response_model=schemas.Msg)
def reset_password(
token: str = Body(...), new_password: str = Body(...), db: Session = Depends(get_db)
):
token: str = Body(...),
new_password: str = Body(...),
db: Session = Depends(deps.get_db),
) -> Any:
"""
Reset password
"""
Expand Down
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,39 @@
from typing import List
from typing import Any, List

from fastapi import APIRouter, Body, Depends, HTTPException
from fastapi.encoders import jsonable_encoder
from pydantic.networks import EmailStr
from sqlalchemy.orm import Session

from app import crud
from app.api.utils.db import get_db
from app.api.utils.security import get_current_active_superuser, get_current_active_user
from app import crud, models, schemas
from app.api import deps
from app.core.config import settings
from app.models.user import User as DBUser
from app.schemas.user import User, UserCreate, UserUpdate
from app.utils import send_new_account_email

router = APIRouter()


@router.get("/", response_model=List[User])
@router.get("/", response_model=List[schemas.User])
def read_users(
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
skip: int = 0,
limit: int = 100,
current_user: DBUser = Depends(get_current_active_superuser),
):
current_user: models.User = Depends(deps.get_current_active_superuser),
) -> Any:
"""
Retrieve users.
"""
users = crud.user.get_multi(db, skip=skip, limit=limit)
return users


@router.post("/", response_model=User)
@router.post("/", response_model=schemas.User)
def create_user(
*,
db: Session = Depends(get_db),
user_in: UserCreate,
current_user: DBUser = Depends(get_current_active_superuser),
):
db: Session = Depends(deps.get_db),
user_in: schemas.UserCreate,
current_user: models.User = Depends(deps.get_current_active_superuser),
) -> Any:
"""
Create new user.
"""
Expand All@@ -54,20 +51,20 @@ def create_user(
return user


@router.put("/me", response_model=User)
@router.put("/me", response_model=schemas.User)
def update_user_me(
*,
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
password: str = Body(None),
full_name: str = Body(None),
email: EmailStr = Body(None),
current_user: DBUser = Depends(get_current_active_user),
):
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Update own user.
"""
current_user_data = jsonable_encoder(current_user)
user_in = UserUpdate(**current_user_data)
user_in = schemas.UserUpdate(**current_user_data)
if password is not None:
user_in.password = password
if full_name is not None:
Expand All@@ -78,25 +75,25 @@ def update_user_me(
return user


@router.get("/me", response_model=User)
@router.get("/me", response_model=schemas.User)
def read_user_me(
db: Session = Depends(get_db),
current_user: DBUser = Depends(get_current_active_user),
):
db: Session = Depends(deps.get_db),
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Get current user.
"""
return current_user


@router.post("/open", response_model=User)
@router.post("/open", response_model=schemas.User)
def create_user_open(
*,
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
password: str = Body(...),
email: EmailStr = Body(...),
full_name: str = Body(None),
):
) -> Any:
"""
Create new user without the need to be logged in.
"""
Expand All@@ -111,17 +108,17 @@ def create_user_open(
status_code=400,
detail="The user with this username already exists in the system",
)
user_in = UserCreate(password=password, email=email, full_name=full_name)
user_in = schemas.UserCreate(password=password, email=email, full_name=full_name)
user = crud.user.create(db, obj_in=user_in)
return user


@router.get("/{user_id}", response_model=User)
@router.get("/{user_id}", response_model=schemas.User)
def read_user_by_id(
user_id: int,
current_user: DBUser = Depends(get_current_active_user),
db: Session = Depends(get_db),
):
current_user: models.User = Depends(deps.get_current_active_user),
db: Session = Depends(deps.get_db),
) -> Any:
"""
Get a specific user by id.
"""
Expand All@@ -135,14 +132,14 @@ def read_user_by_id(
return user


@router.put("/{user_id}", response_model=User)
@router.put("/{user_id}", response_model=schemas.User)
def update_user(
*,
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
user_id: int,
user_in: UserUpdate,
current_user: DBUser = Depends(get_current_active_superuser),
):
user_in: schemas.UserUpdate,
current_user: models.User = Depends(deps.get_current_active_superuser),
) -> Any:
"""
Update a user.
"""
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions {{cookiecutter.project_slug}}/backend/app/.flake8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
[flake8]
max-line-length = 88
exclude = .git,__pycache__,__init__.py,.mypy_cache,.pytest_cache
3 changes: 3 additions & 0 deletions {{cookiecutter.project_slug}}/backend/app/.gitignore
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
.mypy_cache
.coverage
htmlcov
Original file line numberDiff line numberDiff line change
@@ -1,104 +1,99 @@
from typing import List
from typing import Any, List

from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session

from app import crud
from app.api.utils.db import get_db
from app.api.utils.security import get_current_active_user
from app.models.user import User as DBUser
from app.schemas.item import Item, ItemCreate, ItemUpdate
from app import crud, models, schemas
from app.api import deps

router = APIRouter()


@router.get("/", response_model=List[Item])
@router.get("/", response_model=List[schemas.Item])
def read_items(
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
skip: int = 0,
limit: int = 100,
current_user: DBUser = Depends(get_current_active_user),
):
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Retrieve items.
"""
if crud.user.is_superuser(current_user):
items = crud.item.get_multi(db, skip=skip, limit=limit)
else:
items = crud.item.get_multi_by_owner(
db_session=db, owner_id=current_user.id, skip=skip, limit=limit
db=db, owner_id=current_user.id, skip=skip, limit=limit
)
return items


@router.post("/", response_model=Item)
@router.post("/", response_model=schemas.Item)
def create_item(
*,
db: Session = Depends(get_db),
item_in: ItemCreate,
current_user: DBUser = Depends(get_current_active_user),
):
db: Session = Depends(deps.get_db),
item_in: schemas.ItemCreate,
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Create new item.
"""
item = crud.item.create_with_owner(
db_session=db, obj_in=item_in, owner_id=current_user.id
)
item = crud.item.create_with_owner(db=db, obj_in=item_in, owner_id=current_user.id)
return item


@router.put("/{id}", response_model=Item)
@router.put("/{id}", response_model=schemas.Item)
def update_item(
*,
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
id: int,
item_in: ItemUpdate,
current_user: DBUser = Depends(get_current_active_user),
):
item_in: schemas.ItemUpdate,
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Update an item.
"""
item = crud.item.get(db_session=db, id=id)
item = crud.item.get(db=db, id=id)
if not item:
raise HTTPException(status_code=404, detail="Item not found")
if not crud.user.is_superuser(current_user) and (item.owner_id != current_user.id):
raise HTTPException(status_code=400, detail="Not enough permissions")
item = crud.item.update(db_session=db, db_obj=item, obj_in=item_in)
item = crud.item.update(db=db, db_obj=item, obj_in=item_in)
return item


@router.get("/{id}", response_model=Item)
@router.get("/{id}", response_model=schemas.Item)
def read_item(
*,
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
id: int,
current_user: DBUser = Depends(get_current_active_user),
):
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Get item by ID.
"""
item = crud.item.get(db_session=db, id=id)
item = crud.item.get(db=db, id=id)
if not item:
raise HTTPException(status_code=404, detail="Item not found")
if not crud.user.is_superuser(current_user) and (item.owner_id != current_user.id):
raise HTTPException(status_code=400, detail="Not enough permissions")
return item


@router.delete("/{id}", response_model=Item)
@router.delete("/{id}", response_model=schemas.Item)
def delete_item(
*,
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
id: int,
current_user: DBUser = Depends(get_current_active_user),
):
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Delete an item.
"""
item = crud.item.get(db_session=db, id=id)
item = crud.item.get(db=db, id=id)
if not item:
raise HTTPException(status_code=404, detail="Item not found")
if not crud.user.is_superuser(current_user) and (item.owner_id != current_user.id):
raise HTTPException(status_code=400, detail="Not enough permissions")
item = crud.item.remove(db_session=db, id=id)
item = crud.item.remove(db=db, id=id)
return item
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,15 @@
from datetime import timedelta
from typing import Any

from fastapi import APIRouter, Body, Depends, HTTPException
from fastapi.security import OAuth2PasswordRequestForm
from sqlalchemy.orm import Session

from app import crud
from app.api.utils.db import get_db
from app.api.utils.security import get_current_user
from app import crud, models, schemas
from app.api import deps
from app.core import security
from app.core.config import settings
from app.core.jwt import create_access_token
from app.core.security import get_password_hash
from app.models.user import User as DBUser
from app.schemas.msg import Msg
from app.schemas.token import Token
from app.schemas.user import User
from app.utils import (
generate_password_reset_token,
send_reset_password_email,
Expand All@@ -23,10 +19,10 @@
router = APIRouter()


@router.post("/login/access-token", response_model=Token)
@router.post("/login/access-token", response_model=schemas.Token)
def login_access_token(
db: Session = Depends(get_db), form_data: OAuth2PasswordRequestForm = Depends()
):
db: Session = Depends(deps.get_db), form_data: OAuth2PasswordRequestForm = Depends()
) -> Any:
"""
OAuth2 compatible token login, get an access token for future requests
"""
Expand All@@ -39,23 +35,23 @@ def login_access_token(
raise HTTPException(status_code=400, detail="Inactive user")
access_token_expires = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
return {
"access_token": create_access_token(
data={"user_id": user.id}, expires_delta=access_token_expires
"access_token": security.create_access_token(
user.id, expires_delta=access_token_expires
),
"token_type": "bearer",
}


@router.post("/login/test-token", response_model=User)
def test_token(current_user: DBUser = Depends(get_current_user)):
@router.post("/login/test-token", response_model=schemas.User)
def test_token(current_user: models.User = Depends(deps.get_current_user)) -> Any:
"""
Test access token
"""
return current_user


@router.post("/password-recovery/{email}", response_model=Msg)
def recover_password(email: str, db: Session = Depends(get_db)):
@router.post("/password-recovery/{email}", response_model=schemas.Msg)
def recover_password(email: str, db: Session = Depends(deps.get_db)) -> Any:
"""
Password Recovery
"""
Expand All@@ -73,10 +69,12 @@ def recover_password(email: str, db: Session = Depends(get_db)):
return {"msg": "Password recovery email sent"}


@router.post("/reset-password/", response_model=Msg)
@router.post("/reset-password/", response_model=schemas.Msg)
def reset_password(
token: str = Body(...), new_password: str = Body(...), db: Session = Depends(get_db)
):
token: str = Body(...),
new_password: str = Body(...),
db: Session = Depends(deps.get_db),
) -> Any:
"""
Reset password
"""
Expand Down
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,39 @@
from typing import List
from typing import Any, List

from fastapi import APIRouter, Body, Depends, HTTPException
from fastapi.encoders import jsonable_encoder
from pydantic.networks import EmailStr
from sqlalchemy.orm import Session

from app import crud
from app.api.utils.db import get_db
from app.api.utils.security import get_current_active_superuser, get_current_active_user
from app import crud, models, schemas
from app.api import deps
from app.core.config import settings
from app.models.user import User as DBUser
from app.schemas.user import User, UserCreate, UserUpdate
from app.utils import send_new_account_email

router = APIRouter()


@router.get("/", response_model=List[User])
@router.get("/", response_model=List[schemas.User])
def read_users(
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
skip: int = 0,
limit: int = 100,
current_user: DBUser = Depends(get_current_active_superuser),
):
current_user: models.User = Depends(deps.get_current_active_superuser),
) -> Any:
"""
Retrieve users.
"""
users = crud.user.get_multi(db, skip=skip, limit=limit)
return users


@router.post("/", response_model=User)
@router.post("/", response_model=schemas.User)
def create_user(
*,
db: Session = Depends(get_db),
user_in: UserCreate,
current_user: DBUser = Depends(get_current_active_superuser),
):
db: Session = Depends(deps.get_db),
user_in: schemas.UserCreate,
current_user: models.User = Depends(deps.get_current_active_superuser),
) -> Any:
"""
Create new user.
"""
Expand All@@ -54,20 +51,20 @@ def create_user(
return user


@router.put("/me", response_model=User)
@router.put("/me", response_model=schemas.User)
def update_user_me(
*,
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
password: str = Body(None),
full_name: str = Body(None),
email: EmailStr = Body(None),
current_user: DBUser = Depends(get_current_active_user),
):
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Update own user.
"""
current_user_data = jsonable_encoder(current_user)
user_in = UserUpdate(**current_user_data)
user_in = schemas.UserUpdate(**current_user_data)
if password is not None:
user_in.password = password
if full_name is not None:
Expand All@@ -78,25 +75,25 @@ def update_user_me(
return user


@router.get("/me", response_model=User)
@router.get("/me", response_model=schemas.User)
def read_user_me(
db: Session = Depends(get_db),
current_user: DBUser = Depends(get_current_active_user),
):
db: Session = Depends(deps.get_db),
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Get current user.
"""
return current_user


@router.post("/open", response_model=User)
@router.post("/open", response_model=schemas.User)
def create_user_open(
*,
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
password: str = Body(...),
email: EmailStr = Body(...),
full_name: str = Body(None),
):
) -> Any:
"""
Create new user without the need to be logged in.
"""
Expand All@@ -111,17 +108,17 @@ def create_user_open(
status_code=400,
detail="The user with this username already exists in the system",
)
user_in = UserCreate(password=password, email=email, full_name=full_name)
user_in = schemas.UserCreate(password=password, email=email, full_name=full_name)
user = crud.user.create(db, obj_in=user_in)
return user


@router.get("/{user_id}", response_model=User)
@router.get("/{user_id}", response_model=schemas.User)
def read_user_by_id(
user_id: int,
current_user: DBUser = Depends(get_current_active_user),
db: Session = Depends(get_db),
):
current_user: models.User = Depends(deps.get_current_active_user),
db: Session = Depends(deps.get_db),
) -> Any:
"""
Get a specific user by id.
"""
Expand All@@ -135,14 +132,14 @@ def read_user_by_id(
return user


@router.put("/{user_id}", response_model=User)
@router.put("/{user_id}", response_model=schemas.User)
def update_user(
*,
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
user_id: int,
user_in: UserUpdate,
current_user: DBUser = Depends(get_current_active_superuser),
):
user_in: schemas.UserUpdate,
current_user: models.User = Depends(deps.get_current_active_superuser),
) -> Any:
"""
Update a user.
"""
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions {{cookiecutter.project_slug}}/backend/app/.flake8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
[flake8]
max-line-length = 88
exclude = .git,__pycache__,__init__.py,.mypy_cache,.pytest_cache
3 changes: 3 additions & 0 deletions {{cookiecutter.project_slug}}/backend/app/.gitignore
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
.mypy_cache
.coverage
htmlcov
Original file line numberDiff line numberDiff line change
@@ -1,104 +1,99 @@
from typing import List
from typing import Any, List

from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session

from app import crud
from app.api.utils.db import get_db
from app.api.utils.security import get_current_active_user
from app.models.user import User as DBUser
from app.schemas.item import Item, ItemCreate, ItemUpdate
from app import crud, models, schemas
from app.api import deps

router = APIRouter()


@router.get("/", response_model=List[Item])
@router.get("/", response_model=List[schemas.Item])
def read_items(
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
skip: int = 0,
limit: int = 100,
current_user: DBUser = Depends(get_current_active_user),
):
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Retrieve items.
"""
if crud.user.is_superuser(current_user):
items = crud.item.get_multi(db, skip=skip, limit=limit)
else:
items = crud.item.get_multi_by_owner(
db_session=db, owner_id=current_user.id, skip=skip, limit=limit
db=db, owner_id=current_user.id, skip=skip, limit=limit
)
return items


@router.post("/", response_model=Item)
@router.post("/", response_model=schemas.Item)
def create_item(
*,
db: Session = Depends(get_db),
item_in: ItemCreate,
current_user: DBUser = Depends(get_current_active_user),
):
db: Session = Depends(deps.get_db),
item_in: schemas.ItemCreate,
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Create new item.
"""
item = crud.item.create_with_owner(
db_session=db, obj_in=item_in, owner_id=current_user.id
)
item = crud.item.create_with_owner(db=db, obj_in=item_in, owner_id=current_user.id)
return item


@router.put("/{id}", response_model=Item)
@router.put("/{id}", response_model=schemas.Item)
def update_item(
*,
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
id: int,
item_in: ItemUpdate,
current_user: DBUser = Depends(get_current_active_user),
):
item_in: schemas.ItemUpdate,
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Update an item.
"""
item = crud.item.get(db_session=db, id=id)
item = crud.item.get(db=db, id=id)
if not item:
raise HTTPException(status_code=404, detail="Item not found")
if not crud.user.is_superuser(current_user) and (item.owner_id != current_user.id):
raise HTTPException(status_code=400, detail="Not enough permissions")
item = crud.item.update(db_session=db, db_obj=item, obj_in=item_in)
item = crud.item.update(db=db, db_obj=item, obj_in=item_in)
return item


@router.get("/{id}", response_model=Item)
@router.get("/{id}", response_model=schemas.Item)
def read_item(
*,
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
id: int,
current_user: DBUser = Depends(get_current_active_user),
):
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Get item by ID.
"""
item = crud.item.get(db_session=db, id=id)
item = crud.item.get(db=db, id=id)
if not item:
raise HTTPException(status_code=404, detail="Item not found")
if not crud.user.is_superuser(current_user) and (item.owner_id != current_user.id):
raise HTTPException(status_code=400, detail="Not enough permissions")
return item


@router.delete("/{id}", response_model=Item)
@router.delete("/{id}", response_model=schemas.Item)
def delete_item(
*,
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
id: int,
current_user: DBUser = Depends(get_current_active_user),
):
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Delete an item.
"""
item = crud.item.get(db_session=db, id=id)
item = crud.item.get(db=db, id=id)
if not item:
raise HTTPException(status_code=404, detail="Item not found")
if not crud.user.is_superuser(current_user) and (item.owner_id != current_user.id):
raise HTTPException(status_code=400, detail="Not enough permissions")
item = crud.item.remove(db_session=db, id=id)
item = crud.item.remove(db=db, id=id)
return item
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,15 @@
from datetime import timedelta
from typing import Any

from fastapi import APIRouter, Body, Depends, HTTPException
from fastapi.security import OAuth2PasswordRequestForm
from sqlalchemy.orm import Session

from app import crud
from app.api.utils.db import get_db
from app.api.utils.security import get_current_user
from app import crud, models, schemas
from app.api import deps
from app.core import security
from app.core.config import settings
from app.core.jwt import create_access_token
from app.core.security import get_password_hash
from app.models.user import User as DBUser
from app.schemas.msg import Msg
from app.schemas.token import Token
from app.schemas.user import User
from app.utils import (
generate_password_reset_token,
send_reset_password_email,
Expand All@@ -23,10 +19,10 @@
router = APIRouter()


@router.post("/login/access-token", response_model=Token)
@router.post("/login/access-token", response_model=schemas.Token)
def login_access_token(
db: Session = Depends(get_db), form_data: OAuth2PasswordRequestForm = Depends()
):
db: Session = Depends(deps.get_db), form_data: OAuth2PasswordRequestForm = Depends()
) -> Any:
"""
OAuth2 compatible token login, get an access token for future requests
"""
Expand All@@ -39,23 +35,23 @@ def login_access_token(
raise HTTPException(status_code=400, detail="Inactive user")
access_token_expires = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
return {
"access_token": create_access_token(
data={"user_id": user.id}, expires_delta=access_token_expires
"access_token": security.create_access_token(
user.id, expires_delta=access_token_expires
),
"token_type": "bearer",
}


@router.post("/login/test-token", response_model=User)
def test_token(current_user: DBUser = Depends(get_current_user)):
@router.post("/login/test-token", response_model=schemas.User)
def test_token(current_user: models.User = Depends(deps.get_current_user)) -> Any:
"""
Test access token
"""
return current_user


@router.post("/password-recovery/{email}", response_model=Msg)
def recover_password(email: str, db: Session = Depends(get_db)):
@router.post("/password-recovery/{email}", response_model=schemas.Msg)
def recover_password(email: str, db: Session = Depends(deps.get_db)) -> Any:
"""
Password Recovery
"""
Expand All@@ -73,10 +69,12 @@ def recover_password(email: str, db: Session = Depends(get_db)):
return {"msg": "Password recovery email sent"}


@router.post("/reset-password/", response_model=Msg)
@router.post("/reset-password/", response_model=schemas.Msg)
def reset_password(
token: str = Body(...), new_password: str = Body(...), db: Session = Depends(get_db)
):
token: str = Body(...),
new_password: str = Body(...),
db: Session = Depends(deps.get_db),
) -> Any:
"""
Reset password
"""
Expand Down
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,39 @@
from typing import List
from typing import Any, List

from fastapi import APIRouter, Body, Depends, HTTPException
from fastapi.encoders import jsonable_encoder
from pydantic.networks import EmailStr
from sqlalchemy.orm import Session

from app import crud
from app.api.utils.db import get_db
from app.api.utils.security import get_current_active_superuser, get_current_active_user
from app import crud, models, schemas
from app.api import deps
from app.core.config import settings
from app.models.user import User as DBUser
from app.schemas.user import User, UserCreate, UserUpdate
from app.utils import send_new_account_email

router = APIRouter()


@router.get("/", response_model=List[User])
@router.get("/", response_model=List[schemas.User])
def read_users(
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
skip: int = 0,
limit: int = 100,
current_user: DBUser = Depends(get_current_active_superuser),
):
current_user: models.User = Depends(deps.get_current_active_superuser),
) -> Any:
"""
Retrieve users.
"""
users = crud.user.get_multi(db, skip=skip, limit=limit)
return users


@router.post("/", response_model=User)
@router.post("/", response_model=schemas.User)
def create_user(
*,
db: Session = Depends(get_db),
user_in: UserCreate,
current_user: DBUser = Depends(get_current_active_superuser),
):
db: Session = Depends(deps.get_db),
user_in: schemas.UserCreate,
current_user: models.User = Depends(deps.get_current_active_superuser),
) -> Any:
"""
Create new user.
"""
Expand All@@ -54,20 +51,20 @@ def create_user(
return user


@router.put("/me", response_model=User)
@router.put("/me", response_model=schemas.User)
def update_user_me(
*,
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
password: str = Body(None),
full_name: str = Body(None),
email: EmailStr = Body(None),
current_user: DBUser = Depends(get_current_active_user),
):
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Update own user.
"""
current_user_data = jsonable_encoder(current_user)
user_in = UserUpdate(**current_user_data)
user_in = schemas.UserUpdate(**current_user_data)
if password is not None:
user_in.password = password
if full_name is not None:
Expand All@@ -78,25 +75,25 @@ def update_user_me(
return user


@router.get("/me", response_model=User)
@router.get("/me", response_model=schemas.User)
def read_user_me(
db: Session = Depends(get_db),
current_user: DBUser = Depends(get_current_active_user),
):
db: Session = Depends(deps.get_db),
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Get current user.
"""
return current_user


@router.post("/open", response_model=User)
@router.post("/open", response_model=schemas.User)
def create_user_open(
*,
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
password: str = Body(...),
email: EmailStr = Body(...),
full_name: str = Body(None),
):
) -> Any:
"""
Create new user without the need to be logged in.
"""
Expand All@@ -111,17 +108,17 @@ def create_user_open(
status_code=400,
detail="The user with this username already exists in the system",
)
user_in = UserCreate(password=password, email=email, full_name=full_name)
user_in = schemas.UserCreate(password=password, email=email, full_name=full_name)
user = crud.user.create(db, obj_in=user_in)
return user


@router.get("/{user_id}", response_model=User)
@router.get("/{user_id}", response_model=schemas.User)
def read_user_by_id(
user_id: int,
current_user: DBUser = Depends(get_current_active_user),
db: Session = Depends(get_db),
):
current_user: models.User = Depends(deps.get_current_active_user),
db: Session = Depends(deps.get_db),
) -> Any:
"""
Get a specific user by id.
"""
Expand All@@ -135,14 +132,14 @@ def read_user_by_id(
return user


@router.put("/{user_id}", response_model=User)
@router.put("/{user_id}", response_model=schemas.User)
def update_user(
*,
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
user_id: int,
user_in: UserUpdate,
current_user: DBUser = Depends(get_current_active_superuser),
):
user_in: schemas.UserUpdate,
current_user: models.User = Depends(deps.get_current_active_superuser),
) -> Any:
"""
Update a user.
"""
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions {{cookiecutter.project_slug}}/backend/app/.flake8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
[flake8]
max-line-length = 88
exclude = .git,__pycache__,__init__.py,.mypy_cache,.pytest_cache
3 changes: 3 additions & 0 deletions {{cookiecutter.project_slug}}/backend/app/.gitignore
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
.mypy_cache
.coverage
htmlcov
Original file line numberDiff line numberDiff line change
@@ -1,104 +1,99 @@
from typing import List
from typing import Any, List

from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session

from app import crud
from app.api.utils.db import get_db
from app.api.utils.security import get_current_active_user
from app.models.user import User as DBUser
from app.schemas.item import Item, ItemCreate, ItemUpdate
from app import crud, models, schemas
from app.api import deps

router = APIRouter()


@router.get("/", response_model=List[Item])
@router.get("/", response_model=List[schemas.Item])
def read_items(
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
skip: int = 0,
limit: int = 100,
current_user: DBUser = Depends(get_current_active_user),
):
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Retrieve items.
"""
if crud.user.is_superuser(current_user):
items = crud.item.get_multi(db, skip=skip, limit=limit)
else:
items = crud.item.get_multi_by_owner(
db_session=db, owner_id=current_user.id, skip=skip, limit=limit
db=db, owner_id=current_user.id, skip=skip, limit=limit
)
return items


@router.post("/", response_model=Item)
@router.post("/", response_model=schemas.Item)
def create_item(
*,
db: Session = Depends(get_db),
item_in: ItemCreate,
current_user: DBUser = Depends(get_current_active_user),
):
db: Session = Depends(deps.get_db),
item_in: schemas.ItemCreate,
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Create new item.
"""
item = crud.item.create_with_owner(
db_session=db, obj_in=item_in, owner_id=current_user.id
)
item = crud.item.create_with_owner(db=db, obj_in=item_in, owner_id=current_user.id)
return item


@router.put("/{id}", response_model=Item)
@router.put("/{id}", response_model=schemas.Item)
def update_item(
*,
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
id: int,
item_in: ItemUpdate,
current_user: DBUser = Depends(get_current_active_user),
):
item_in: schemas.ItemUpdate,
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Update an item.
"""
item = crud.item.get(db_session=db, id=id)
item = crud.item.get(db=db, id=id)
if not item:
raise HTTPException(status_code=404, detail="Item not found")
if not crud.user.is_superuser(current_user) and (item.owner_id != current_user.id):
raise HTTPException(status_code=400, detail="Not enough permissions")
item = crud.item.update(db_session=db, db_obj=item, obj_in=item_in)
item = crud.item.update(db=db, db_obj=item, obj_in=item_in)
return item


@router.get("/{id}", response_model=Item)
@router.get("/{id}", response_model=schemas.Item)
def read_item(
*,
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
id: int,
current_user: DBUser = Depends(get_current_active_user),
):
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Get item by ID.
"""
item = crud.item.get(db_session=db, id=id)
item = crud.item.get(db=db, id=id)
if not item:
raise HTTPException(status_code=404, detail="Item not found")
if not crud.user.is_superuser(current_user) and (item.owner_id != current_user.id):
raise HTTPException(status_code=400, detail="Not enough permissions")
return item


@router.delete("/{id}", response_model=Item)
@router.delete("/{id}", response_model=schemas.Item)
def delete_item(
*,
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
id: int,
current_user: DBUser = Depends(get_current_active_user),
):
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Delete an item.
"""
item = crud.item.get(db_session=db, id=id)
item = crud.item.get(db=db, id=id)
if not item:
raise HTTPException(status_code=404, detail="Item not found")
if not crud.user.is_superuser(current_user) and (item.owner_id != current_user.id):
raise HTTPException(status_code=400, detail="Not enough permissions")
item = crud.item.remove(db_session=db, id=id)
item = crud.item.remove(db=db, id=id)
return item
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,15 @@
from datetime import timedelta
from typing import Any

from fastapi import APIRouter, Body, Depends, HTTPException
from fastapi.security import OAuth2PasswordRequestForm
from sqlalchemy.orm import Session

from app import crud
from app.api.utils.db import get_db
from app.api.utils.security import get_current_user
from app import crud, models, schemas
from app.api import deps
from app.core import security
from app.core.config import settings
from app.core.jwt import create_access_token
from app.core.security import get_password_hash
from app.models.user import User as DBUser
from app.schemas.msg import Msg
from app.schemas.token import Token
from app.schemas.user import User
from app.utils import (
generate_password_reset_token,
send_reset_password_email,
Expand All@@ -23,10 +19,10 @@
router = APIRouter()


@router.post("/login/access-token", response_model=Token)
@router.post("/login/access-token", response_model=schemas.Token)
def login_access_token(
db: Session = Depends(get_db), form_data: OAuth2PasswordRequestForm = Depends()
):
db: Session = Depends(deps.get_db), form_data: OAuth2PasswordRequestForm = Depends()
) -> Any:
"""
OAuth2 compatible token login, get an access token for future requests
"""
Expand All@@ -39,23 +35,23 @@ def login_access_token(
raise HTTPException(status_code=400, detail="Inactive user")
access_token_expires = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
return {
"access_token": create_access_token(
data={"user_id": user.id}, expires_delta=access_token_expires
"access_token": security.create_access_token(
user.id, expires_delta=access_token_expires
),
"token_type": "bearer",
}


@router.post("/login/test-token", response_model=User)
def test_token(current_user: DBUser = Depends(get_current_user)):
@router.post("/login/test-token", response_model=schemas.User)
def test_token(current_user: models.User = Depends(deps.get_current_user)) -> Any:
"""
Test access token
"""
return current_user


@router.post("/password-recovery/{email}", response_model=Msg)
def recover_password(email: str, db: Session = Depends(get_db)):
@router.post("/password-recovery/{email}", response_model=schemas.Msg)
def recover_password(email: str, db: Session = Depends(deps.get_db)) -> Any:
"""
Password Recovery
"""
Expand All@@ -73,10 +69,12 @@ def recover_password(email: str, db: Session = Depends(get_db)):
return {"msg": "Password recovery email sent"}


@router.post("/reset-password/", response_model=Msg)
@router.post("/reset-password/", response_model=schemas.Msg)
def reset_password(
token: str = Body(...), new_password: str = Body(...), db: Session = Depends(get_db)
):
token: str = Body(...),
new_password: str = Body(...),
db: Session = Depends(deps.get_db),
) -> Any:
"""
Reset password
"""
Expand Down
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,39 @@
from typing import List
from typing import Any, List

from fastapi import APIRouter, Body, Depends, HTTPException
from fastapi.encoders import jsonable_encoder
from pydantic.networks import EmailStr
from sqlalchemy.orm import Session

from app import crud
from app.api.utils.db import get_db
from app.api.utils.security import get_current_active_superuser, get_current_active_user
from app import crud, models, schemas
from app.api import deps
from app.core.config import settings
from app.models.user import User as DBUser
from app.schemas.user import User, UserCreate, UserUpdate
from app.utils import send_new_account_email

router = APIRouter()


@router.get("/", response_model=List[User])
@router.get("/", response_model=List[schemas.User])
def read_users(
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
skip: int = 0,
limit: int = 100,
current_user: DBUser = Depends(get_current_active_superuser),
):
current_user: models.User = Depends(deps.get_current_active_superuser),
) -> Any:
"""
Retrieve users.
"""
users = crud.user.get_multi(db, skip=skip, limit=limit)
return users


@router.post("/", response_model=User)
@router.post("/", response_model=schemas.User)
def create_user(
*,
db: Session = Depends(get_db),
user_in: UserCreate,
current_user: DBUser = Depends(get_current_active_superuser),
):
db: Session = Depends(deps.get_db),
user_in: schemas.UserCreate,
current_user: models.User = Depends(deps.get_current_active_superuser),
) -> Any:
"""
Create new user.
"""
Expand All@@ -54,20 +51,20 @@ def create_user(
return user


@router.put("/me", response_model=User)
@router.put("/me", response_model=schemas.User)
def update_user_me(
*,
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
password: str = Body(None),
full_name: str = Body(None),
email: EmailStr = Body(None),
current_user: DBUser = Depends(get_current_active_user),
):
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Update own user.
"""
current_user_data = jsonable_encoder(current_user)
user_in = UserUpdate(**current_user_data)
user_in = schemas.UserUpdate(**current_user_data)
if password is not None:
user_in.password = password
if full_name is not None:
Expand All@@ -78,25 +75,25 @@ def update_user_me(
return user


@router.get("/me", response_model=User)
@router.get("/me", response_model=schemas.User)
def read_user_me(
db: Session = Depends(get_db),
current_user: DBUser = Depends(get_current_active_user),
):
db: Session = Depends(deps.get_db),
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Get current user.
"""
return current_user


@router.post("/open", response_model=User)
@router.post("/open", response_model=schemas.User)
def create_user_open(
*,
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
password: str = Body(...),
email: EmailStr = Body(...),
full_name: str = Body(None),
):
) -> Any:
"""
Create new user without the need to be logged in.
"""
Expand All@@ -111,17 +108,17 @@ def create_user_open(
status_code=400,
detail="The user with this username already exists in the system",
)
user_in = UserCreate(password=password, email=email, full_name=full_name)
user_in = schemas.UserCreate(password=password, email=email, full_name=full_name)
user = crud.user.create(db, obj_in=user_in)
return user


@router.get("/{user_id}", response_model=User)
@router.get("/{user_id}", response_model=schemas.User)
def read_user_by_id(
user_id: int,
current_user: DBUser = Depends(get_current_active_user),
db: Session = Depends(get_db),
):
current_user: models.User = Depends(deps.get_current_active_user),
db: Session = Depends(deps.get_db),
) -> Any:
"""
Get a specific user by id.
"""
Expand All@@ -135,14 +132,14 @@ def read_user_by_id(
return user


@router.put("/{user_id}", response_model=User)
@router.put("/{user_id}", response_model=schemas.User)
def update_user(
*,
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
user_id: int,
user_in: UserUpdate,
current_user: DBUser = Depends(get_current_active_superuser),
):
user_in: schemas.UserUpdate,
current_user: models.User = Depends(deps.get_current_active_superuser),
) -> Any:
"""
Update a user.
"""
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions {{cookiecutter.project_slug}}/backend/app/.flake8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
[flake8]
max-line-length = 88
exclude = .git,__pycache__,__init__.py,.mypy_cache,.pytest_cache
3 changes: 3 additions & 0 deletions {{cookiecutter.project_slug}}/backend/app/.gitignore
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
.mypy_cache
.coverage
htmlcov
Original file line numberDiff line numberDiff line change
@@ -1,104 +1,99 @@
from typing import List
from typing import Any, List

from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session

from app import crud
from app.api.utils.db import get_db
from app.api.utils.security import get_current_active_user
from app.models.user import User as DBUser
from app.schemas.item import Item, ItemCreate, ItemUpdate
from app import crud, models, schemas
from app.api import deps

router = APIRouter()


@router.get("/", response_model=List[Item])
@router.get("/", response_model=List[schemas.Item])
def read_items(
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
skip: int = 0,
limit: int = 100,
current_user: DBUser = Depends(get_current_active_user),
):
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Retrieve items.
"""
if crud.user.is_superuser(current_user):
items = crud.item.get_multi(db, skip=skip, limit=limit)
else:
items = crud.item.get_multi_by_owner(
db_session=db, owner_id=current_user.id, skip=skip, limit=limit
db=db, owner_id=current_user.id, skip=skip, limit=limit
)
return items


@router.post("/", response_model=Item)
@router.post("/", response_model=schemas.Item)
def create_item(
*,
db: Session = Depends(get_db),
item_in: ItemCreate,
current_user: DBUser = Depends(get_current_active_user),
):
db: Session = Depends(deps.get_db),
item_in: schemas.ItemCreate,
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Create new item.
"""
item = crud.item.create_with_owner(
db_session=db, obj_in=item_in, owner_id=current_user.id
)
item = crud.item.create_with_owner(db=db, obj_in=item_in, owner_id=current_user.id)
return item


@router.put("/{id}", response_model=Item)
@router.put("/{id}", response_model=schemas.Item)
def update_item(
*,
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
id: int,
item_in: ItemUpdate,
current_user: DBUser = Depends(get_current_active_user),
):
item_in: schemas.ItemUpdate,
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Update an item.
"""
item = crud.item.get(db_session=db, id=id)
item = crud.item.get(db=db, id=id)
if not item:
raise HTTPException(status_code=404, detail="Item not found")
if not crud.user.is_superuser(current_user) and (item.owner_id != current_user.id):
raise HTTPException(status_code=400, detail="Not enough permissions")
item = crud.item.update(db_session=db, db_obj=item, obj_in=item_in)
item = crud.item.update(db=db, db_obj=item, obj_in=item_in)
return item


@router.get("/{id}", response_model=Item)
@router.get("/{id}", response_model=schemas.Item)
def read_item(
*,
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
id: int,
current_user: DBUser = Depends(get_current_active_user),
):
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Get item by ID.
"""
item = crud.item.get(db_session=db, id=id)
item = crud.item.get(db=db, id=id)
if not item:
raise HTTPException(status_code=404, detail="Item not found")
if not crud.user.is_superuser(current_user) and (item.owner_id != current_user.id):
raise HTTPException(status_code=400, detail="Not enough permissions")
return item


@router.delete("/{id}", response_model=Item)
@router.delete("/{id}", response_model=schemas.Item)
def delete_item(
*,
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
id: int,
current_user: DBUser = Depends(get_current_active_user),
):
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Delete an item.
"""
item = crud.item.get(db_session=db, id=id)
item = crud.item.get(db=db, id=id)
if not item:
raise HTTPException(status_code=404, detail="Item not found")
if not crud.user.is_superuser(current_user) and (item.owner_id != current_user.id):
raise HTTPException(status_code=400, detail="Not enough permissions")
item = crud.item.remove(db_session=db, id=id)
item = crud.item.remove(db=db, id=id)
return item
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,15 @@
from datetime import timedelta
from typing import Any

from fastapi import APIRouter, Body, Depends, HTTPException
from fastapi.security import OAuth2PasswordRequestForm
from sqlalchemy.orm import Session

from app import crud
from app.api.utils.db import get_db
from app.api.utils.security import get_current_user
from app import crud, models, schemas
from app.api import deps
from app.core import security
from app.core.config import settings
from app.core.jwt import create_access_token
from app.core.security import get_password_hash
from app.models.user import User as DBUser
from app.schemas.msg import Msg
from app.schemas.token import Token
from app.schemas.user import User
from app.utils import (
generate_password_reset_token,
send_reset_password_email,
Expand All@@ -23,10 +19,10 @@
router = APIRouter()


@router.post("/login/access-token", response_model=Token)
@router.post("/login/access-token", response_model=schemas.Token)
def login_access_token(
db: Session = Depends(get_db), form_data: OAuth2PasswordRequestForm = Depends()
):
db: Session = Depends(deps.get_db), form_data: OAuth2PasswordRequestForm = Depends()
) -> Any:
"""
OAuth2 compatible token login, get an access token for future requests
"""
Expand All@@ -39,23 +35,23 @@ def login_access_token(
raise HTTPException(status_code=400, detail="Inactive user")
access_token_expires = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
return {
"access_token": create_access_token(
data={"user_id": user.id}, expires_delta=access_token_expires
"access_token": security.create_access_token(
user.id, expires_delta=access_token_expires
),
"token_type": "bearer",
}


@router.post("/login/test-token", response_model=User)
def test_token(current_user: DBUser = Depends(get_current_user)):
@router.post("/login/test-token", response_model=schemas.User)
def test_token(current_user: models.User = Depends(deps.get_current_user)) -> Any:
"""
Test access token
"""
return current_user


@router.post("/password-recovery/{email}", response_model=Msg)
def recover_password(email: str, db: Session = Depends(get_db)):
@router.post("/password-recovery/{email}", response_model=schemas.Msg)
def recover_password(email: str, db: Session = Depends(deps.get_db)) -> Any:
"""
Password Recovery
"""
Expand All@@ -73,10 +69,12 @@ def recover_password(email: str, db: Session = Depends(get_db)):
return {"msg": "Password recovery email sent"}


@router.post("/reset-password/", response_model=Msg)
@router.post("/reset-password/", response_model=schemas.Msg)
def reset_password(
token: str = Body(...), new_password: str = Body(...), db: Session = Depends(get_db)
):
token: str = Body(...),
new_password: str = Body(...),
db: Session = Depends(deps.get_db),
) -> Any:
"""
Reset password
"""
Expand Down
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,39 @@
from typing import List
from typing import Any, List

from fastapi import APIRouter, Body, Depends, HTTPException
from fastapi.encoders import jsonable_encoder
from pydantic.networks import EmailStr
from sqlalchemy.orm import Session

from app import crud
from app.api.utils.db import get_db
from app.api.utils.security import get_current_active_superuser, get_current_active_user
from app import crud, models, schemas
from app.api import deps
from app.core.config import settings
from app.models.user import User as DBUser
from app.schemas.user import User, UserCreate, UserUpdate
from app.utils import send_new_account_email

router = APIRouter()


@router.get("/", response_model=List[User])
@router.get("/", response_model=List[schemas.User])
def read_users(
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
skip: int = 0,
limit: int = 100,
current_user: DBUser = Depends(get_current_active_superuser),
):
current_user: models.User = Depends(deps.get_current_active_superuser),
) -> Any:
"""
Retrieve users.
"""
users = crud.user.get_multi(db, skip=skip, limit=limit)
return users


@router.post("/", response_model=User)
@router.post("/", response_model=schemas.User)
def create_user(
*,
db: Session = Depends(get_db),
user_in: UserCreate,
current_user: DBUser = Depends(get_current_active_superuser),
):
db: Session = Depends(deps.get_db),
user_in: schemas.UserCreate,
current_user: models.User = Depends(deps.get_current_active_superuser),
) -> Any:
"""
Create new user.
"""
Expand All@@ -54,20 +51,20 @@ def create_user(
return user


@router.put("/me", response_model=User)
@router.put("/me", response_model=schemas.User)
def update_user_me(
*,
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
password: str = Body(None),
full_name: str = Body(None),
email: EmailStr = Body(None),
current_user: DBUser = Depends(get_current_active_user),
):
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Update own user.
"""
current_user_data = jsonable_encoder(current_user)
user_in = UserUpdate(**current_user_data)
user_in = schemas.UserUpdate(**current_user_data)
if password is not None:
user_in.password = password
if full_name is not None:
Expand All@@ -78,25 +75,25 @@ def update_user_me(
return user


@router.get("/me", response_model=User)
@router.get("/me", response_model=schemas.User)
def read_user_me(
db: Session = Depends(get_db),
current_user: DBUser = Depends(get_current_active_user),
):
db: Session = Depends(deps.get_db),
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Get current user.
"""
return current_user


@router.post("/open", response_model=User)
@router.post("/open", response_model=schemas.User)
def create_user_open(
*,
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
password: str = Body(...),
email: EmailStr = Body(...),
full_name: str = Body(None),
):
) -> Any:
"""
Create new user without the need to be logged in.
"""
Expand All@@ -111,17 +108,17 @@ def create_user_open(
status_code=400,
detail="The user with this username already exists in the system",
)
user_in = UserCreate(password=password, email=email, full_name=full_name)
user_in = schemas.UserCreate(password=password, email=email, full_name=full_name)
user = crud.user.create(db, obj_in=user_in)
return user


@router.get("/{user_id}", response_model=User)
@router.get("/{user_id}", response_model=schemas.User)
def read_user_by_id(
user_id: int,
current_user: DBUser = Depends(get_current_active_user),
db: Session = Depends(get_db),
):
current_user: models.User = Depends(deps.get_current_active_user),
db: Session = Depends(deps.get_db),
) -> Any:
"""
Get a specific user by id.
"""
Expand All@@ -135,14 +132,14 @@ def read_user_by_id(
return user


@router.put("/{user_id}", response_model=User)
@router.put("/{user_id}", response_model=schemas.User)
def update_user(
*,
db: Session = Depends(get_db),
db: Session = Depends(deps.get_db),
user_id: int,
user_in: UserUpdate,
current_user: DBUser = Depends(get_current_active_superuser),
):
user_in: schemas.UserUpdate,
current_user: models.User = Depends(deps.get_current_active_superuser),
) -> Any:
"""
Update a user.
"""
Expand Down
Loading