Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: extending openAPI #226

Merged
merged 64 commits into from Feb 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
307e584
feat: adding holidays to calendar as events
Jan 30, 2021
f8f4d5d
fix: unused import and long lines
Jan 30, 2021
a064a89
fix: add os to get folder location for test
Jan 30, 2021
468d18b
fix: add line break
Jan 30, 2021
a1fec2b
fix: another try for pytest relative folder for my test
Jan 30, 2021
af814ad
fix: another try for pytest relative folder for my test
Jan 30, 2021
94f5ede
fix: another try for pytest relative folder for my test
Jan 30, 2021
6597f7a
fix: fixed merge request comments
Jan 31, 2021
bcc34a2
fix: fixed merge request comments
Jan 31, 2021
d67a4e3
fix: fixed merge request comments
Jan 31, 2021
d2d1d52
fix: fixed awaited test failure
Jan 31, 2021
e2ff48e
fix: fixed blank line
Jan 31, 2021
1d7b2b7
fix: removed unused import
Jan 31, 2021
c38afb1
fix: renamed 128 into variable
Jan 31, 2021
ec85764
fix: fix line too long
Jan 31, 2021
dfbd98c
fix: removed not needed code
Jan 31, 2021
6292b0c
fix: fixed mr comments - added one more test and minor fixes
Feb 1, 2021
53c3b00
fix: fixed new line at end of file
Feb 1, 2021
02daca2
feat: extending openAPI
Feb 7, 2021
e711ebf
Merge branch 'develop' into extending_openapi
Feb 7, 2021
a6a8a8e
fix: solve merge conflig
Feb 7, 2021
6627476
fix: flake8 comments
Feb 7, 2021
6014a78
fix: flake8 comments
Feb 7, 2021
3388982
fix: added type annotations
Feb 7, 2021
b79af9c
Merge remote-tracking branch 'upstream/develop' into holiday
Feb 7, 2021
edfe81e
fix: solve merge conflict
Feb 7, 2021
5a1ef2d
fix: solve pr comments
Feb 9, 2021
18c4749
Merge branch 'develop' into extending_openapi
Feb 9, 2021
9a5ba6c
merge conflicts
Feb 9, 2021
9ee10fb
fix: flake8 comments
Feb 9, 2021
a9b40a1
fix: flake8 comments
Feb 9, 2021
b487b78
fix: flake8 comments
Feb 9, 2021
b042297
fix: added type annotations
Feb 9, 2021
410aae1
Merge branch 'develop' into holiday
Feb 9, 2021
018f82d
fix: merge conflict
Feb 9, 2021
e42f6be
fix: fixed type annotation for test
Feb 9, 2021
65e8507
fix: fixed mr comments
Feb 10, 2021
c4d6b30
Merge branch 'develop' into holiday
Feb 10, 2021
43d1344
fix: merge conflict
Feb 10, 2021
94bca6c
fix: solve mr comments
Feb 10, 2021
ff9d7b5
Merge branch 'holiday' into extending_openapi
Feb 10, 2021
e76e093
fix: solve mr comments
Feb 10, 2021
79af524
fix: solve mr comments
Feb 11, 2021
652f818
Merge branch 'develop' into extending_openapi
Feb 11, 2021
107bb28
fix: mr comments
Feb 11, 2021
fdf677f
fix: mr comments
Feb 11, 2021
e796079
fix: mr comments
Feb 11, 2021
c01a968
Merge branch 'develop' into extending_openapi
Feb 11, 2021
ada457a
fix: removed unused import
Feb 11, 2021
2adb3ce
fix: added tests
Feb 13, 2021
66181cd
Merge branch 'develop' into extending_openapi
Feb 13, 2021
51f41b0
fix: flake8 error
Feb 13, 2021
92da383
Merge branch 'develop' into extending_openapi
yammesicka Feb 14, 2021
e584c87
fix: minor fix for holiday route - already merged
Feb 14, 2021
84744e0
Merge remote-tracking branch 'origin/extending_openapi' into extendin…
Feb 14, 2021
8c76e35
fix: fix merge issues
Feb 14, 2021
e3bced2
fix: fix flake8 issues
Feb 14, 2021
7634804
fix: added minor fixes fro holiday - merging it to here as its branch…
Feb 14, 2021
1dda1b4
fix: remove unused import
Feb 14, 2021
5be40bd
fix: fix pr comments
Feb 15, 2021
18ad95d
Merge branch 'develop' into extending_openapi
Feb 15, 2021
21780ed
fix: merge conflicts
Feb 15, 2021
758af51
feat: change css size to relative units
Feb 15, 2021
9dbc02b
feat: change css size to relative units
Feb 15, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
34 changes: 29 additions & 5 deletions app/main.py
Expand Up @@ -5,8 +5,13 @@

from app.internal.languages import set_ui_language
from app.internal.security.ouath2 import auth_exception_handler
from app.utils.extending_openapi import custom_openapi
from app.routers.salary import routes as salary
from fastapi import Depends, FastAPI, Request
from fastapi.openapi.docs import (
get_swagger_ui_html,
get_swagger_ui_oauth2_redirect_html,
)
from fastapi.staticfiles import StaticFiles
from starlette.status import HTTP_401_UNAUTHORIZED
from sqlalchemy.orm import Session
Expand All @@ -25,7 +30,7 @@ def create_tables(engine, psql_environment):

create_tables(engine, config.PSQL_ENVIRONMENT)

app = FastAPI()
app = FastAPI(title="Pylander", docs_url=None)
app.mount("/static", StaticFiles(directory=STATIC_PATH), name="static")
app.mount("/media", StaticFiles(directory=MEDIA_PATH), name="media")
app.logger = logger
Expand All @@ -36,16 +41,31 @@ def create_tables(engine, psql_environment):
# This MUST come before the app.routers imports.
set_ui_language()


from app.routers import ( # noqa: E402

agenda, calendar, categories, celebrity, currency, dayview,
email, event, export, four_o_four, invitation, login, logout, profile,
register, search, telegram, weekview, whatsapp,
register, search, telegram, user, weekview, whatsapp,
)

json_data_loader.load_to_db(next(get_db()))


@app.get("/docs", include_in_schema=False)
async def custom_swagger_ui_html():
return get_swagger_ui_html(
openapi_url=app.openapi_url,
title=app.title + " - Swagger UI",
oauth2_redirect_url=app.swagger_ui_oauth2_redirect_url,
swagger_js_url="/static/swagger/swagger-ui-bundle.js",
swagger_css_url="/static/swagger/swagger-ui.css",
)


@app.get(app.swagger_ui_oauth2_redirect_url, include_in_schema=False)
async def swagger_ui_redirect():
return get_swagger_ui_oauth2_redirect_html()


routers_to_include = [
agenda.router,
calendar.router,
Expand All @@ -66,6 +86,7 @@ def create_tables(engine, psql_environment):
salary.router,
search.router,
telegram.router,
user.router,
whatsapp.router,
]

Expand All @@ -75,11 +96,14 @@ def create_tables(engine, psql_environment):

# TODO: I add the quote day to the home page
# until the relevant calendar view will be developed.
@app.get("/")
@app.get("/", include_in_schema=False)
@logger.catch()
async def home(request: Request, db: Session = Depends(get_db)):
quote = daily_quotes.quote_per_day(db)
return templates.TemplateResponse("index.html", {
"request": request,
"quote": quote,
})


custom_openapi(app)
2 changes: 1 addition & 1 deletion app/routers/agenda.py
Expand Up @@ -27,7 +27,7 @@ def calc_dates_range_for_agenda(
return start, end


@router.get("/agenda")
@router.get("/agenda", include_in_schema=False)
def agenda(
request: Request,
db: Session = Depends(get_db),
Expand Down
1 change: 1 addition & 0 deletions app/routers/calendar.py
Expand Up @@ -11,6 +11,7 @@
prefix="/calendar/month",
tags=["calendar"],
responses={404: {"description": "Not found"}},
include_in_schema=False
)

ADD_DAYS_ON_SCROLL: int = 42
Expand Down
15 changes: 14 additions & 1 deletion app/routers/categories.py
Expand Up @@ -35,7 +35,7 @@ class Config:


# TODO(issue#29): get current user_id from session
@router.get("/")
@router.get("/", include_in_schema=False)
def get_categories(request: Request,
db_session: Session = Depends(get_db)) -> List[Category]:
if validate_request_params(request.query_params):
Expand All @@ -46,6 +46,19 @@ def get_categories(request: Request,
f"unallowed params.")


@router.get("/list")
def get_all_categories(
db_session: Session = Depends(get_db)) -> List[Category]:
return db_session.query(Category).all()


@router.get("/")
def get_categories_by_user_id(
user_id: int, db_session: Session = Depends(get_db)
) -> List[Category]:
return get_user_categories(db_session, user_id)


# TODO(issue#29): get current user_id from session
@router.post("/")
async def set_category(category: CategoryModel,
Expand Down
2 changes: 1 addition & 1 deletion app/routers/dayview.py
Expand Up @@ -122,7 +122,7 @@ def get_events_and_attributes(
yield (event, DivAttributes(event, day))


@router.get('/day/{date}')
@router.get('/day/{date}', include_in_schema=False)
async def dayview(
request: Request, date: str, session=Depends(get_db), view='day',
):
Expand Down
56 changes: 42 additions & 14 deletions app/routers/event.py
@@ -1,9 +1,10 @@
from datetime import datetime
from datetime import datetime as dt
import json
from operator import attrgetter
from typing import Any, Dict, List, Optional, Tuple

from fastapi import APIRouter, Depends, HTTPException, Request
from pydantic import BaseModel
from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.orm import Session
from sqlalchemy.orm.exc import MultipleResultsFound, NoResultFound
Expand All @@ -27,8 +28,8 @@
START_FORMAT = '%A, %d/%m/%Y %H:%M'
UPDATE_EVENTS_FIELDS = {
'title': str,
'start': datetime,
'end': datetime,
'start': dt,
'end': dt,
'availability': bool,
'content': (str, type(None)),
'location': (str, type(None)),
Expand All @@ -43,22 +44,49 @@
)


class EventModel(BaseModel):
title: str
start: dt
end: dt
content: str
owner_id: int
location: str


@router.get("/")
async def get_events(session=Depends(get_db)):
return session.query(Event).all()


@router.post("/")
async def create_event_api(event: EventModel, session=Depends(get_db)):
create_event(db=session,
title=event.title,
start=event.start,
end=event.start,
content=event.content,
owner_id=event.owner_id,
location=event.location)
return {'success': True}

galzunited marked this conversation as resolved.
Show resolved Hide resolved

@router.get("/edit", include_in_schema=False)
@router.get("/edit")
async def eventedit(request: Request) -> Response:
return templates.TemplateResponse("event/eventedit.html",
{"request": request})


@router.post("/edit")
@router.post("/edit", include_in_schema=False)
async def create_new_event(request: Request,
session=Depends(get_db)) -> Response:
data = await request.form()
title = data['title']
content = data['description']
start = datetime.strptime(data['start_date'] + ' ' + data['start_time'],
TIME_FORMAT)
end = datetime.strptime(data['end_date'] + ' ' + data['end_time'],
TIME_FORMAT)
start = dt.strptime(data['start_date'] + ' ' +
data['start_time'], TIME_FORMAT)
end = dt.strptime(data['end_date'] + ' ' + data['end_time'],
TIME_FORMAT)
owner_id = get_current_user(session).id
availability = data.get('availability', 'True') == 'True'
location = data['location']
Expand All @@ -83,7 +111,7 @@ async def create_new_event(request: Request,
status_code=status.HTTP_302_FOUND)


@router.get("/{event_id}")
@router.get("/{event_id}", include_in_schema=False)
async def eventview(request: Request, event_id: int,
db: Session = Depends(get_db)) -> Response:
event, comments, end_format = get_event_data(db, event_id)
Expand Down Expand Up @@ -127,8 +155,8 @@ def by_id(db: Session, event_id: int) -> Event:
return event


def is_end_date_before_start_date(start_date: datetime,
end_date: datetime) -> bool:
def is_end_date_before_start_date(start_date: dt,
end_date: dt) -> bool:
"""Check if the start date is earlier than the end date"""
return start_date > end_date

Expand Down Expand Up @@ -286,15 +314,15 @@ def delete_event(event_id: int,
event = by_id(db, event_id)
participants = get_participants_emails_by_event(db, event_id)
_delete_event(db, event)
if participants and event.start > datetime.now():
if participants and event.start > dt.now():
pass
# TODO: Send them a cancellation notice
# if the deletion is successful
return RedirectResponse(
url="/calendar", status_code=status.HTTP_200_OK)


def is_date_before(start_time: datetime, end_time: datetime) -> bool:
def is_date_before(start_time: dt, end_time: dt) -> bool:
"""Check if the start_date is smaller then the end_time"""
try:
return start_time < end_time
Expand Down Expand Up @@ -333,7 +361,7 @@ async def add_comment(request: Request, event_id: int,
'user_id': get_current_user(session).id,
'event_id': event_id,
'content': form['comment'],
'time': datetime.now(),
'time': dt.now(),
}
create_model(session, Comment, **data)
path = router.url_path_for('view_comments', event_id=event_id)
Expand Down
13 changes: 7 additions & 6 deletions app/routers/invitation.py
Expand Up @@ -17,7 +17,7 @@
)


@router.get("/")
@router.get("/", include_in_schema=False)
def view_invitations(request: Request, db: Session = Depends(get_db)):
return templates.TemplateResponse("invitations.html", {
"request": request,
Expand All @@ -29,7 +29,7 @@ def view_invitations(request: Request, db: Session = Depends(get_db)):
})


@router.post("/")
@router.post("/", include_in_schema=False)
async def accept_invitations(
request: Request,
db: Session = Depends(get_db)
Expand All @@ -44,7 +44,8 @@ async def accept_invitations(
return RedirectResponse(url=url, status_code=HTTP_302_FOUND)


def get_all_invitations(session: Session, **param) -> List[Invitation]:
@router.get("/get_all_invitations")
def get_all_invitations(session=Depends(get_db), **param) -> List[Invitation]:
"""Returns all invitations filter by param."""

try:
Expand All @@ -55,9 +56,9 @@ def get_all_invitations(session: Session, **param) -> List[Invitation]:
return invitations


def get_invitation_by_id(
invitation_id: int, session: Session
) -> Union[Invitation, None]:
@router.post("/get_invitation_by_id")
def get_invitation_by_id(invitation_id: int,
session=Depends(get_db)) -> Union[Invitation, None]:
"""Returns a invitation by an id.
if id does not exist, returns None."""

Expand Down
2 changes: 1 addition & 1 deletion app/routers/profile.py
Expand Up @@ -165,7 +165,7 @@ def get_image_crop_area(width, height):


@router.post("/holidays/update")
async def update_holidays(
async def update(
file: UploadFile = File(...), session=Depends(get_db)):
icsfile = await file.read()
holidays = get_holidays_from_file(icsfile.decode(), session)
Expand Down
4 changes: 2 additions & 2 deletions app/routers/search.py
Expand Up @@ -7,7 +7,7 @@
router = APIRouter()


@router.get("/search")
@router.get("/search", include_in_schema=False)
def search(request: Request):
# Made up user details until there's a user login system
current_username = "Chuck Norris"
Expand All @@ -18,7 +18,7 @@ def search(request: Request):
})


@router.post("/search")
@router.post("/search", include_in_schema=False)
async def show_results(
request: Request,
keywords: str = Form(None),
Expand Down
2 changes: 1 addition & 1 deletion app/routers/telegram.py
Expand Up @@ -12,7 +12,7 @@
)


@router.post("/")
@router.post("/", include_in_schema=False)
async def bot_client(req: dict = Body(...), session=Depends(get_db)):
chat = Chat(req)

Expand Down
33 changes: 33 additions & 0 deletions app/routers/user.py
@@ -1,10 +1,43 @@
from typing import List
from pydantic import BaseModel, Field

from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.orm import Session

from app.dependencies import get_db
from app.database.models import Event, User, UserEvent
from app.internal.utils import save
from fastapi import APIRouter, Depends

router = APIRouter(
prefix="/user",
tags=["user"],
responses={404: {"description": "Not found"}},
)


class UserModel(BaseModel):
username: str
password: str
email: str = Field(regex='^\\S+@\\S+\\.\\S+$')
language: str
language_id: int


@router.get("/list")
async def get_all_users(session=Depends(get_db)):
return session.query(User).all()


@router.get("/")
async def get_user(id: int, session=Depends(get_db)):
return session.query(User).filter_by(id=id).first()


@router.post("/")
def manually_create_user(user: UserModel, session=Depends(get_db)):
create_user(**user.dict(), session=session)
return f'User {user.username} successfully created'


def create_user(username: str,
Expand Down
4 changes: 2 additions & 2 deletions app/routers/whatsapp.py
@@ -1,9 +1,9 @@
from typing import Optional
from urllib.parse import urlencode

from fastapi import APIRouter
from urllib.parse import urlencode

router = APIRouter()
router = APIRouter(tags=["utils"])


@router.get("/whatsapp")
Expand Down