Skip to content

Commit 7fd8e97

Browse files
committed
Merge branch 'master' into clean-up-getting-latest-released-service
2 parents 33a8a91 + 4cf8ef1 commit 7fd8e97

File tree

103 files changed

+4754
-1100
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

103 files changed

+4754
-1100
lines changed

.env-devel

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,10 @@ DIRECTOR_SERVICES_CUSTOM_CONSTRAINTS=null
8686
DIRECTOR_TRACING=null
8787

8888
DOCKER_API_PROXY_HOST=docker-api-proxy
89-
DOCKER_API_PROXY_PASSWORD=null
89+
DOCKER_API_PROXY_PASSWORD=admin
9090
DOCKER_API_PROXY_PORT=8888
9191
DOCKER_API_PROXY_SECURE=False
92-
DOCKER_API_PROXY_USER=null
92+
DOCKER_API_PROXY_USER=admin
9393

9494
EFS_USER_ID=8006
9595
EFS_USER_NAME=efs

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
⬆️ Upgrade dependencies.
1111
📝 Add or update documentation.
1212
🔨 Add or update development scripts.
13+
✅ Add, update or pass tests.
1314
🔒️ Fix security issues.
1415
⚠️ Changes in ops configuration etc. are required before deploying.
1516
[ Please add a link to the associated ops-issue or PR, such as in https://github.com/ITISFoundation/osparc-ops-environments or https://git.speag.com/oSparc/osparc-infra ]
@@ -28,32 +29,16 @@ or from https://gitmoji.dev/
2829

2930

3031
## Related issue/s
31-
32-
<!-- Link pull request to an issue
33-
SEE https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue
34-
35-
- resolves ITISFoundation/osparc-issues#428
36-
- fixes #26
37-
-->
32+
<!-- LINK to other issues and add prefix `closes`, `fixes`, `resolves`-->
3833

3934

4035
## How to test
4136

4237
<!-- Give REVIEWERS some hits or code snippets on how could this be tested -->
4338

44-
## Dev-ops checklist
45-
46-
- [ ] No ENV changes or I properly updated ENV ([read the instruction](https://git.speag.com/oSparc/osparc-ops-deployment-configuration/-/blob/configs/README.md?ref_type=heads#how-to-update-env-variables))
47-
48-
<!-- Some checks that might help your code run stable on production, and help devops assess criticality.
49-
Modified from https://oschvr.com/posts/what-id-like-as-sre/
39+
## Dev-ops
5040

51-
- How can DevOps check the health of the service ?
52-
- How can DevOps safely and gracefully restart the service ?
53-
- How and why would this code fail ?
54-
- What kind of metrics are you exposing ?
55-
- Is there any documentation/design specification for the service ?
56-
- How (e.g. through which loglines) can DevOps detect unexpected situations that require escalation to human ?
57-
- What are the resource limitations (CPU, RAM) expected for this service ?
58-
- Are all relevant variables documented and adjustable via environment variables (i.e. no hardcoded magic numbers) ?
41+
<!--
42+
- No changes /updated ENV. SEE https://git.speag.com/oSparc/osparc-ops-deployment-configuration/-/blob/configs/README.md?ref_type=heads#how-to-update-env-variables)
43+
- SEE docs/devops-checklist.md
5944
-->

.github/workflows/ci-testing-deploy.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -573,7 +573,7 @@ jobs:
573573
- name: install uv
574574
uses: astral-sh/setup-uv@v6
575575
with:
576-
version: "0.5.x"
576+
version: "0.6.x"
577577
enable-cache: false
578578
cache-dependency-glob: "**/notifications/requirements/ci.txt"
579579
- name: show system version

api/specs/web-server/_projects_comments.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from typing import Literal
1212

1313
from _common import assert_handler_signature_against_model
14-
from fastapi import APIRouter
14+
from fastapi import APIRouter, status
1515
from models_library.generics import Envelope
1616
from models_library.projects import ProjectID
1717
from models_library.projects_comments import CommentID, ProjectsCommentsAPI
@@ -41,7 +41,8 @@
4141
"/projects/{project_uuid}/comments",
4242
response_model=Envelope[dict[Literal["comment_id"], CommentID]],
4343
description="Create a new comment for a specific project. The request body should contain the comment contents and user information.",
44-
status_code=201,
44+
status_code=status.HTTP_201_CREATED,
45+
deprecated=True,
4546
)
4647
async def create_project_comment(
4748
project_uuid: ProjectID, body: _ProjectCommentsBodyParams
@@ -57,6 +58,7 @@ async def create_project_comment(
5758
"/projects/{project_uuid}/comments",
5859
response_model=Envelope[list[ProjectsCommentsAPI]],
5960
description="Retrieve all comments for a specific project.",
61+
deprecated=True,
6062
)
6163
async def list_project_comments(
6264
project_uuid: ProjectID, limit: int = 20, offset: NonNegativeInt = 0
@@ -72,6 +74,7 @@ async def list_project_comments(
7274
"/projects/{project_uuid}/comments/{comment_id}",
7375
response_model=Envelope[ProjectsCommentsAPI],
7476
description="Update the contents of a specific comment for a project. The request body should contain the updated comment contents.",
77+
deprecated=True,
7578
)
7679
async def update_project_comment(
7780
project_uuid: ProjectID,
@@ -88,7 +91,8 @@ async def update_project_comment(
8891
@router.delete(
8992
"/projects/{project_uuid}/comments/{comment_id}",
9093
description="Delete a specific comment associated with a project.",
91-
status_code=204,
94+
status_code=status.HTTP_204_NO_CONTENT,
95+
deprecated=True,
9296
)
9397
async def delete_project_comment(project_uuid: ProjectID, comment_id: CommentID): ...
9498

@@ -102,6 +106,7 @@ async def delete_project_comment(project_uuid: ProjectID, comment_id: CommentID)
102106
"/projects/{project_uuid}/comments/{comment_id}",
103107
response_model=Envelope[ProjectsCommentsAPI],
104108
description="Retrieve a specific comment by its ID within a project.",
109+
deprecated=True,
105110
)
106111
async def get_project_comment(project_uuid: ProjectID, comment_id: CommentID): ...
107112

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
"""Helper script to automatically generate OAS
2+
3+
This OAS are the source of truth
4+
"""
5+
6+
# pylint: disable=redefined-outer-name
7+
# pylint: disable=unused-argument
8+
# pylint: disable=unused-variable
9+
# pylint: disable=too-many-arguments
10+
11+
12+
from typing import Annotated
13+
14+
from fastapi import APIRouter, Depends, status
15+
from models_library.api_schemas_webserver.projects_conversations import (
16+
ConversationMessageRestGet,
17+
ConversationRestGet,
18+
)
19+
from models_library.generics import Envelope
20+
from models_library.rest_pagination import Page
21+
from simcore_service_webserver._meta import API_VTAG
22+
from simcore_service_webserver.projects._controller._rest_schemas import (
23+
ProjectPathParams,
24+
)
25+
from simcore_service_webserver.projects._controller.conversations_rest import (
26+
_ListProjectConversationMessagesQueryParams,
27+
_ListProjectConversationsQueryParams,
28+
_ProjectConversationMessagesCreateBodyParams,
29+
_ProjectConversationMessagesPutBodyParams,
30+
_ProjectConversationsCreateBodyParams,
31+
_ProjectConversationsMessagesPathParams,
32+
_ProjectConversationsPathParams,
33+
_ProjectConversationsPutBodyParams,
34+
)
35+
36+
router = APIRouter(
37+
prefix=f"/{API_VTAG}",
38+
tags=[
39+
"projects",
40+
"conversations",
41+
],
42+
)
43+
44+
45+
#
46+
# API entrypoints PROJECTS/*/CONVERSATIONS/*
47+
#
48+
49+
50+
@router.post(
51+
"/projects/{project_id}/conversations",
52+
response_model=Envelope[ConversationRestGet],
53+
status_code=status.HTTP_201_CREATED,
54+
)
55+
async def create_project_conversation(
56+
_params: Annotated[ProjectPathParams, Depends()],
57+
_body: _ProjectConversationsCreateBodyParams,
58+
): ...
59+
60+
61+
@router.get(
62+
"/projects/{project_id}/conversations",
63+
response_model=Page[ConversationRestGet],
64+
)
65+
async def list_project_conversations(
66+
_params: Annotated[ProjectPathParams, Depends()],
67+
_query: Annotated[_ListProjectConversationsQueryParams, Depends()],
68+
): ...
69+
70+
71+
@router.put(
72+
"/projects/{project_id}/conversations/{conversation_id}",
73+
response_model=Envelope[ConversationRestGet],
74+
)
75+
async def update_project_conversation(
76+
_params: Annotated[_ProjectConversationsPathParams, Depends()],
77+
_body: _ProjectConversationsPutBodyParams,
78+
): ...
79+
80+
81+
@router.delete(
82+
"/projects/{project_id}/conversations/{conversation_id}",
83+
status_code=status.HTTP_204_NO_CONTENT,
84+
)
85+
async def delete_project_conversation(
86+
_params: Annotated[_ProjectConversationsPathParams, Depends()],
87+
): ...
88+
89+
90+
@router.get(
91+
"/projects/{project_id}/conversations/{conversation_id}",
92+
response_model=Envelope[ConversationRestGet],
93+
)
94+
async def get_project_conversation(
95+
_params: Annotated[_ProjectConversationsPathParams, Depends()],
96+
): ...
97+
98+
99+
### Conversation Messages
100+
101+
102+
@router.post(
103+
"/projects/{project_id}/conversations/{conversation_id}/messages",
104+
response_model=Envelope[ConversationMessageRestGet],
105+
status_code=status.HTTP_201_CREATED,
106+
)
107+
async def create_project_conversation_message(
108+
_params: Annotated[_ProjectConversationsPathParams, Depends()],
109+
_body: _ProjectConversationMessagesCreateBodyParams,
110+
): ...
111+
112+
113+
@router.get(
114+
"/projects/{project_id}/conversations/{conversation_id}/messages",
115+
response_model=Page[ConversationMessageRestGet],
116+
)
117+
async def list_project_conversation_messages(
118+
_params: Annotated[_ProjectConversationsPathParams, Depends()],
119+
_query: Annotated[_ListProjectConversationMessagesQueryParams, Depends()],
120+
): ...
121+
122+
123+
@router.put(
124+
"/projects/{project_id}/conversations/{conversation_id}/messages/{message_id}",
125+
response_model=Envelope[ConversationMessageRestGet],
126+
)
127+
async def update_project_conversation_message(
128+
_params: Annotated[_ProjectConversationsMessagesPathParams, Depends()],
129+
_body: _ProjectConversationMessagesPutBodyParams,
130+
): ...
131+
132+
133+
@router.delete(
134+
"/projects/{project_id}/conversations/{conversation_id}/messages/{message_id}",
135+
status_code=status.HTTP_204_NO_CONTENT,
136+
)
137+
async def delete_project_conversation_message(
138+
_params: Annotated[_ProjectConversationsMessagesPathParams, Depends()],
139+
): ...
140+
141+
142+
@router.get(
143+
"/projects/{project_id}/conversations/{conversation_id}/messages/{message_id}",
144+
response_model=Envelope[ConversationMessageRestGet],
145+
)
146+
async def get_project_conversation_message(
147+
_params: Annotated[_ProjectConversationsMessagesPathParams, Depends()],
148+
): ...

api/specs/web-server/openapi.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
"_projects",
4646
"_projects_access_rights",
4747
"_projects_comments",
48+
"_projects_conversations",
4849
"_projects_folders",
4950
"_projects_metadata",
5051
"_projects_nodes",

docs/devops-checklist.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Devops checklist
2+
3+
- No ENV changes or I properly updated ENV ([read the instruction](https://git.speag.com/oSparc/osparc-ops-deployment-configuration/-/blob/configs/README.md?ref_type=heads#how-to-update-env-variables))
4+
5+
- Some checks that might help your code run stable on production, and help devops assess criticality.
6+
- How can DevOps check the health of the service ?
7+
- How can DevOps safely and gracefully restart the service ?
8+
- How and why would this code fail ?
9+
- What kind of metrics are you exposing ?
10+
- Is there any documentation/design specification for the service ?
11+
- How (e.g. through which loglines) can DevOps detect unexpected situations that require escalation to human ?
12+
- What are the resource limitations (CPU, RAM) expected for this service ?
13+
- Are all relevant variables documented and adjustable via environment variables (i.e. no hardcoded magic numbers) ?
14+
15+
Ref: Modified from https://oschvr.com/posts/what-id-like-as-sre/
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
from datetime import datetime
2+
from typing import Annotated, Self
3+
4+
from pydantic import Field
5+
6+
from ..conversations import (
7+
ConversationGetDB,
8+
ConversationID,
9+
ConversationMessageGetDB,
10+
ConversationMessageID,
11+
ConversationMessageType,
12+
ConversationType,
13+
)
14+
from ..groups import GroupID
15+
from ..products import ProductName
16+
from ..projects import ProjectID
17+
from ._base import InputSchema, OutputSchema
18+
19+
### PROJECT CONVERSATION -------------------------------------------------------------------
20+
21+
22+
class ConversationRestGet(OutputSchema):
23+
conversation_id: ConversationID
24+
product_name: ProductName
25+
name: Annotated[str, Field(max_length=50)]
26+
project_uuid: ProjectID | None
27+
user_group_id: GroupID
28+
type: ConversationType
29+
created: datetime
30+
modified: datetime
31+
32+
@classmethod
33+
def from_domain_model(cls, domain: ConversationGetDB) -> Self:
34+
return cls(
35+
conversation_id=domain.conversation_id,
36+
product_name=domain.product_name,
37+
name=domain.name,
38+
project_uuid=domain.project_uuid,
39+
user_group_id=domain.user_group_id,
40+
type=domain.type,
41+
created=domain.created,
42+
modified=domain.modified,
43+
)
44+
45+
46+
class ConversationPatch(InputSchema):
47+
name: str | None = None
48+
49+
50+
### PROJECT CONVERSATION MESSAGES ---------------------------------------------------------------
51+
52+
53+
class ConversationMessageRestGet(OutputSchema):
54+
message_id: ConversationMessageID
55+
conversation_id: ConversationID
56+
user_group_id: GroupID
57+
content: Annotated[str, Field(max_length=4096)]
58+
type: ConversationMessageType
59+
created: datetime
60+
modified: datetime
61+
62+
@classmethod
63+
def from_domain_model(cls, domain: ConversationMessageGetDB) -> Self:
64+
return cls(
65+
message_id=domain.message_id,
66+
conversation_id=domain.conversation_id,
67+
user_group_id=domain.user_group_id,
68+
content=domain.content,
69+
type=domain.type,
70+
created=domain.created,
71+
modified=domain.modified,
72+
)
73+
74+
75+
class ConversationMessagePatch(InputSchema):
76+
content: str | None = None

0 commit comments

Comments
 (0)