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

build: Updated pydantic version to 2.4 #70

Merged
merged 3 commits into from
Oct 5, 2023
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
47 changes: 47 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,50 @@ dmypy.json
.history/
.vscode/settings.json
coverage.lcov
venv_3_11_6/lib64
venv_3_11_6/pyvenv.cfg
venv_3_11_6/bin/activate
venv_3_11_6/bin/activate.csh
venv_3_11_6/bin/activate.fish
venv_3_11_6/bin/Activate.ps1
venv_3_11_6/bin/beanie
venv_3_11_6/bin/chardetect
venv_3_11_6/bin/coverage
venv_3_11_6/bin/coverage-3.11
venv_3_11_6/bin/coverage3
venv_3_11_6/bin/dmypy
venv_3_11_6/bin/dotenv
venv_3_11_6/bin/email_validator
venv_3_11_6/bin/faker
venv_3_11_6/bin/flake8
venv_3_11_6/bin/httpx
venv_3_11_6/bin/mypy
venv_3_11_6/bin/mypyc
venv_3_11_6/bin/pip
venv_3_11_6/bin/pip3
venv_3_11_6/bin/pip3.11
venv_3_11_6/bin/py.test
venv_3_11_6/bin/pycodestyle
venv_3_11_6/bin/pyflakes
venv_3_11_6/bin/pytest
venv_3_11_6/bin/python
venv_3_11_6/bin/python3
venv_3_11_6/bin/python3.11
venv_3_11_6/bin/stubgen
venv_3_11_6/bin/stubtest
venv_3_11_6/bin/tox
venv_3_11_6/bin/uvicorn
venv_3_11_6/bin/virtualenv
venv_3_11_6/bin/watchfiles
venv_3_12/lib64
venv_3_12/pyvenv.cfg
venv_3_12/bin/activate
venv_3_12/bin/activate.csh
venv_3_12/bin/activate.fish
venv_3_12/bin/Activate.ps1
venv_3_12/bin/pip
venv_3_12/bin/pip3
venv_3_12/bin/pip3.12
venv_3_12/bin/python
venv_3_12/bin/python3
venv_3_12/bin/python3.12
13 changes: 7 additions & 6 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@ classifiers = [
"Programming Language :: Python :: 3",
]
dependencies = [
'fastapi==0.98.0',
'uvicorn[standard]==0.22.0',
'fastapi-users[beanie]==11.0.0',
'beanie==1.19.0',
'colorama==0.4.6',
'beanie',
'colorama',
'fastapi',
'fastapi-users[beanie]',
'pydantic-settings',
'uvicorn[standard]',
]

[project.scripts]
Expand Down Expand Up @@ -94,4 +95,4 @@ warn_unreachable = true
no_implicit_reexport = true
plugins = [
"pydantic.mypy"
]
]
11 changes: 6 additions & 5 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
fastapi==0.98.0
uvicorn[standard]==0.22.0
fastapi-users[beanie]==11.0.0
beanie==1.19.0
colorama==0.4.6
beanie==1.22.6
colorama==0.4.6
fastapi-users[beanie]==12.1.2
fastapi==0.103.2
pydantic-settings==2.0.3
uvicorn[standard]==0.23.2
24 changes: 12 additions & 12 deletions src/unipoll_api/actions/group.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

# # Create a group list for output schema using the search results
# for group in search_result:
# group_list.append(GroupSchemas.Group(**group.dict()))
# group_list.append(GroupSchemas.Group(**group.model_dump()))

# return GroupSchemas.GroupList(groups=group_list)

Expand All @@ -24,9 +24,9 @@
async def get_group(group: Group, include_members: bool = False, include_policies: bool = False) -> GroupSchemas.Group:
members = (await get_group_members(group)).members if include_members else None
policies = (await get_group_policies(group)).policies if include_policies else None
workspace = WorkspaceSchemas.Workspace(**group.workspace.dict(exclude={"members", # type: ignore
"policies",
"groups"}))
workspace = WorkspaceSchemas.Workspace(**group.workspace.model_dump(exclude={"members", # type: ignore
"policies",
"groups"}))
# Return the workspace with the fetched resources
return GroupSchemas.Group(id=group.id,
name=group.name,
Expand Down Expand Up @@ -62,7 +62,7 @@ async def update_group(group: Group,
if save_changes:
await Group.save(group)
# Return the updated group
return GroupSchemas.Group(**group.dict())
return GroupSchemas.Group(**group.model_dump())


# Delete a group
Expand All @@ -88,7 +88,7 @@ async def get_group_members(group: Group) -> MemberSchemas.MemberList:
req_permissions = Permissions.GroupPermissions["get_group_members"] # type: ignore
if Permissions.check_permission(permissions, req_permissions):
for member in group.members: # type: ignore
member_data = member.dict(include={'id', 'first_name', 'last_name', 'email'})
member_data = member.model_dump(include={'id', 'first_name', 'last_name', 'email'})
member_scheme = MemberSchemas.Member(**member_data)
member_list.append(member_scheme)
# Return the list of members
Expand All @@ -107,7 +107,7 @@ async def add_group_members(group: Group, member_data: MemberSchemas.AddMembers)
await group.add_member(account, Permissions.GROUP_BASIC_PERMISSIONS)
await Group.save(group)
# Return the list of members added to the group
return MemberSchemas.MemberList(members=[MemberSchemas.Member(**account.dict()) for account in account_list])
return MemberSchemas.MemberList(members=[MemberSchemas.Member(**account.model_dump()) for account in account_list])


# Remove a member from a workspace
Expand All @@ -127,7 +127,7 @@ async def remove_group_member(group: Group, account_id: ResourceID | None):
raise GroupExceptions.UserNotMember(group, account)
# Remove the account from the group
if await group.remove_member(account):
member_list = [MemberSchemas.Member(**account.dict()) for account in group.members] # type: ignore
member_list = [MemberSchemas.Member(**account.model_dump()) for account in group.members] # type: ignore
return MemberSchemas.MemberList(members=member_list)
raise GroupExceptions.ErrorWhileRemovingMember(group, account)

Expand All @@ -153,11 +153,11 @@ async def get_group_policies(group: Group) -> PolicySchemas.PolicyList:
# TODO: Replace with custom exception
raise ResourceExceptions.InternalServerError("get_group_policies() => Policy holder not found")
# Convert the policy_holder to a Member schema
policy_holder = MemberSchemas.Member(**policy_holder.dict()) # type: ignore
policy_holder = MemberSchemas.Member(**policy_holder.model_dump()) # type: ignore
policy_list.append(PolicySchemas.PolicyShort(id=policy.id,
policy_holder_type=policy.policy_holder_type,
# Exclude unset fields(i.e. "description" for Account)
policy_holder=policy_holder.dict(exclude_unset=True),
policy_holder=policy_holder.model_dump(exclude_unset=True),
permissions=permissions))
return PolicySchemas.PolicyList(policies=policy_list)

Expand All @@ -183,7 +183,7 @@ async def get_group_policy(group: Group, account_id: ResourceID | None):
# await group.fetch_link(Group.policies)
user_permissions = await Permissions.get_all_permissions(group, account)
res = {'permissions': Permissions.GroupPermissions(user_permissions).name.split('|'), # type: ignore
'account': AccountSchemas.AccountShort(**account.dict())}
'account': AccountSchemas.AccountShort(**account.model_dump())}
return res


Expand Down Expand Up @@ -240,4 +240,4 @@ async def set_group_policy(group: Group,
# Return the updated policy
return PolicySchemas.PolicyOutput(
permissions=Permissions.GroupPermissions(policy.permissions).name.split('|'), # type: ignore
policy_holder=MemberSchemas.Member(**policy_holder.dict())) # type: ignore
policy_holder=MemberSchemas.Member(**policy_holder.model_dump())) # type: ignore
6 changes: 3 additions & 3 deletions src/unipoll_api/actions/policy.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,11 @@ async def get_policy(policy: Policy) -> PolicySchemas.PolicyShort:
if not policy_holder:
raise PolicyExceptions.PolicyHolderNotFound(ph_ref)

policy_holder = MemberSchemas.Member(**policy_holder.dict()) # type: ignore
policy_holder = MemberSchemas.Member(**policy_holder.model_dump()) # type: ignore
permissions = Permissions.WorkspacePermissions(policy.permissions).name.split('|') # type: ignore
return PolicySchemas.PolicyShort(id=policy.id,
policy_holder_type=policy.policy_holder_type,
policy_holder=policy_holder.dict(exclude_unset=True),
policy_holder=policy_holder.model_dump(exclude_unset=True),
permissions=permissions)

# if not account and account_id:
Expand All @@ -76,4 +76,4 @@ async def get_policy(policy: Policy) -> PolicySchemas.PolicyShort:
# user_permissions = await Permissions.get_all_permissions(workspace, account)
# return PolicySchemas.PolicyOutput(
# permissions=Permissions.WorkspacePermissions(user_permissions).name.split('|'), # type: ignore
# policy_holder=MemberSchemas.Member(**account.dict()))
# policy_holder=MemberSchemas.Member(**account.model_dump()))
10 changes: 5 additions & 5 deletions src/unipoll_api/actions/poll.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ async def get_polls(workspace: Workspace | None = None) -> PollSchemas.PollList:
poll_list.append(poll)
# Build poll list and return the result
for poll in poll_list:
poll_list.append(PollSchemas.PollShort(**poll.dict())) # type: ignore
poll_list.append(PollSchemas.PollShort(**poll.model_dump())) # type: ignore
return PollSchemas.PollList(polls=poll_list)


Expand All @@ -48,7 +48,7 @@ async def get_poll(poll: Poll,
if Permissions.check_permission(permissions, req_permissions):
policies = (await get_poll_policies(poll)).policies

workspace = WorkspaceSchemas.WorkspaceShort(**poll.workspace.dict()) # type: ignore
workspace = WorkspaceSchemas.WorkspaceShort(**poll.workspace.model_dump()) # type: ignore

# Return the workspace with the fetched resources
return PollSchemas.PollResponse(id=poll.id,
Expand All @@ -65,7 +65,7 @@ async def get_poll_questions(poll: Poll) -> QuestionSchemas.QuestionList:
print("Poll: ", poll.questions)
question_list = []
for question in poll.questions:
# question_data = question.dict()
# question_data = question.model_dump()
question_scheme = QuestionSchemas.Question(**question)
question_list.append(question_scheme)
# Return the list of questions
Expand All @@ -88,11 +88,11 @@ async def get_poll_policies(poll: Poll) -> PolicySchemas.PolicyList:
# TODO: Replace with custom exception
raise ResourceExceptions.InternalServerError("get_poll_policies() => Policy holder not found")
# Convert the policy_holder to a Member schema
policy_holder = MemberSchemas.Member(**policy_holder.dict()) # type: ignore
policy_holder = MemberSchemas.Member(**policy_holder.model_dump()) # type: ignore
policy_list.append(PolicySchemas.PolicyShort(id=policy.id,
policy_holder_type=policy.policy_holder_type,
# Exclude unset fields(i.e. "description" for Account)
policy_holder=policy_holder.dict(exclude_unset=True),
policy_holder=policy_holder.model_dump(exclude_unset=True),
permissions=permissions))
return PolicySchemas.PolicyList(policies=policy_list)

Expand Down
2 changes: 1 addition & 1 deletion src/unipoll_api/actions/superuser.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ async def get_all_workspaces() -> WorkspaceSchemas.WorkspaceList:

# Create a workspace list for output schema using the search results
for workspace in search_result:
workspace_list.append(WorkspaceSchemas.Workspace(**workspace.dict()))
workspace_list.append(WorkspaceSchemas.Workspace(**workspace.model_dump()))

return WorkspaceSchemas.WorkspaceList(workspaces=workspace_list)
22 changes: 11 additions & 11 deletions src/unipoll_api/actions/workspace.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ async def get_workspaces() -> WorkspaceSchemas.WorkspaceList:
# Create a workspace list for output schema using the search results
for workspace in search_result:
workspace_list.append(WorkspaceSchemas.WorkspaceShort(
**workspace.dict(exclude={'members', 'groups', 'permissions'})))
**workspace.model_dump(exclude={'members', 'groups', 'permissions'})))

return WorkspaceSchemas.WorkspaceList(workspaces=workspace_list)

Expand Down Expand Up @@ -54,7 +54,7 @@ async def create_workspace(input_data: WorkspaceSchemas.WorkspaceCreateInput) ->
await Workspace.save(new_workspace, link_rule=WriteRules.WRITE)

# Specify fields for output schema
return WorkspaceSchemas.WorkspaceCreateOutput(**new_workspace.dict())
return WorkspaceSchemas.WorkspaceCreateOutput(**new_workspace.model_dump(include={'id', 'name', 'description'}))


# Get a workspace
Expand Down Expand Up @@ -96,7 +96,7 @@ async def update_workspace(workspace: Workspace,
if save_changes:
await Workspace.save(workspace)
# Return the updated workspace
return WorkspaceSchemas.Workspace(**workspace.dict())
return WorkspaceSchemas.Workspace(**workspace.model_dump())


# Delete a workspace
Expand All @@ -120,7 +120,7 @@ async def get_workspace_members(workspace: Workspace) -> MemberSchemas.MemberLis
req_permissions = Permissions.WorkspacePermissions["get_workspace_members"] # type: ignore
if Permissions.check_permission(permissions, req_permissions):
for member in workspace.members: # type: ignore
member_data = member.dict(include={'id', 'first_name', 'last_name', 'email'})
member_data = member.model_dump(include={'id', 'first_name', 'last_name', 'email'})
member_scheme = MemberSchemas.Member(**member_data)
member_list.append(member_scheme)
# Return the list of members
Expand All @@ -140,7 +140,7 @@ async def add_workspace_members(workspace: Workspace,
await workspace.add_member(account, Permissions.WORKSPACE_BASIC_PERMISSIONS, save=False)
await Workspace.save(workspace, link_rule=WriteRules.WRITE)
# Return the list of members added to the group
return MemberSchemas.MemberList(members=[MemberSchemas.Member(**account.dict()) for account in account_list])
return MemberSchemas.MemberList(members=[MemberSchemas.Member(**account.model_dump()) for account in account_list])


# Remove a member from a workspace
Expand All @@ -159,7 +159,7 @@ async def remove_workspace_member(workspace: Workspace, account_id: ResourceID):
# Remove the account from the workspace
if await workspace.remove_member(account):
# Return the list of members added to the group
member_list = [MemberSchemas.Member(**account.dict()) for account in workspace.members] # type: ignore
member_list = [MemberSchemas.Member(**account.model_dump()) for account in workspace.members] # type: ignore
return MemberSchemas.MemberList(members=member_list)
raise WorkspaceExceptions.ErrorWhileRemovingMember(workspace, account)

Expand All @@ -171,7 +171,7 @@ async def get_groups(workspace: Workspace) -> GroupSchemas.GroupList:
# Check if the user has permission to get all groups
req_permissions = Permissions.WorkspacePermissions["get_groups"] # type: ignore
if Permissions.check_permission(permissions, req_permissions):
groups = [GroupSchemas.GroupShort(**group.dict()) for group in workspace.groups] # type: ignore
groups = [GroupSchemas.GroupShort(**group.model_dump()) for group in workspace.groups] # type: ignore
# Otherwise, return only the groups where the user has permission to get the group
else:
groups = []
Expand All @@ -180,7 +180,7 @@ async def get_groups(workspace: Workspace) -> GroupSchemas.GroupList:
required_permission = Permissions.GroupPermissions['get_group']
if Permissions.check_permission(Permissions.GroupPermissions(user_permissions), # type: ignore
required_permission):
groups.append(GroupSchemas.GroupShort(**group.dict())) # type: ignore
groups.append(GroupSchemas.GroupShort(**group.model_dump())) # type: ignore
# Return the list of groups
return GroupSchemas.GroupList(groups=groups)

Expand Down Expand Up @@ -222,7 +222,7 @@ async def create_group(workspace: Workspace,
await Workspace.save(workspace, link_rule=WriteRules.WRITE)

# Return the new group
return GroupSchemas.GroupCreateOutput(**new_group.dict())
return GroupSchemas.GroupCreateOutput(**new_group.model_dump(include={'id', 'name', 'description'}))


# Get all policies of a workspace
Expand Down Expand Up @@ -305,7 +305,7 @@ async def set_workspace_policy(workspace: Workspace,
# Return the updated policy
return PolicySchemas.PolicyOutput(
permissions=Permissions.WorkspacePermissions(policy.permissions).name.split('|'), # type: ignore
policy_holder=MemberSchemas.Member(**policy_holder.dict())) # type: ignore
policy_holder=MemberSchemas.Member(**policy_holder.model_dump())) # type: ignore


# Get a list of polls in a workspace
Expand Down Expand Up @@ -339,4 +339,4 @@ async def create_poll(workspace: Workspace, input_data: PollSchemas.CreatePollRe
await Workspace.save(workspace, link_rule=WriteRules.WRITE)

# Return the new poll
return PollSchemas.PollResponse(**new_poll.dict())
return PollSchemas.PollResponse(**new_poll.model_dump())
4 changes: 2 additions & 2 deletions src/unipoll_api/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
app.include_router(router)

# Add CORS middleware to allow cross-origin requests
origins = settings.origins
origins = settings.origins.split(",")

# Middleware
app.add_middleware(
Expand All @@ -46,7 +46,7 @@ async def on_startup() -> None:
route.operation_id = route.name

await init_beanie(
database=mainDB,
database=mainDB, # type: ignore
document_models=documentModels # type: ignore
)

Expand Down
19 changes: 9 additions & 10 deletions src/unipoll_api/config.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from pydantic import BaseSettings, EmailStr, Field
from pydantic import EmailStr, Field
from functools import lru_cache
import importlib.metadata
import unipoll_api.__version__ as version_file
from pydantic_settings import BaseSettings, SettingsConfigDict


try:
Expand All @@ -17,18 +18,16 @@ class Settings(BaseSettings): # type: ignore
app_description: str = Field(default=("An Open Source API for creating surveys and polls "
"to assist in university research."),
title="App Description", description="A description of the API.")
admin_email: EmailStr = Field(default=EmailStr("admin@unipoll.cc"),
title="Admin Email", description="The email address of the admin of the API.")
admin_email: EmailStr = Field(default="admin@example.com",
title="Admin Email", description="The email address of the API administrator.")
mongodb_url: str = Field(default="mongodb://localhost:27017",
title="MongoDB URL", description="The URL of the MongoDB database.")
secrete_key: str = Field(default="secret", title="Secrete Key", description="The secrete key of the API.")
origins = "*".split(",")
host = "0.0.0.0"
port = 9000
reload = True

class Config:
env_file = ".env"
origins: str = "*"
host: str = "0.0.0.0"
port: int = 9000
reload: bool = True
model_config = SettingsConfigDict(env_file=".env")


@lru_cache()
Expand Down
Loading