Skip to content

Commit 1345b13

Browse files
authored
Merge pull request #33 from nyjc-computing/dev/sync-devcontainer
fix: add end_slash parameter to ResourceCollection.make_path() (#31) and devcontainer sync
2 parents ad6b8c1 + f9fb64b commit 1345b13

10 files changed

Lines changed: 50 additions & 48 deletions

File tree

.devcontainer/Dockerfile

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
FROM mcr.microsoft.com/devcontainers/python:3.12
2+
3+
# Install GitHub CLI
4+
RUN rm -f /etc/apt/sources.list.d/yarn*.list || true && \
5+
rm -f /etc/apt/trusted.gpg.d/yarn*.gpg || true && \
6+
curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg && \
7+
echo "deb [signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | tee /etc/apt/sources.list.d/github-cli.list && \
8+
apt-get update && \
9+
apt-get install -y gh && \
10+
apt-get clean && rm -rf /var/lib/apt/lists/*
11+
12+
# Install Railway CLI
13+
RUN curl -fsSL https://railway.app/install.sh | bash
14+
15+
# Configure Git
16+
RUN git config --global pull.ff true
17+
18+
# Install Poetry
19+
RUN pip install poetry && \
20+
poetry config virtualenvs.in-project true && \
21+
poetry config virtualenvs.create true
22+
23+
# Install poetry-shell plugin
24+
RUN poetry self add poetry-plugin-shell

.devcontainer/devcontainer.json

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
{
22
"name": "Python Flask DevContainer",
3-
"image": "mcr.microsoft.com/devcontainers/python:3.12",
3+
"build": {
4+
"dockerfile": "Dockerfile"
5+
},
46
"customizations": {
57
"vscode": {
68
"settings": {
@@ -12,6 +14,6 @@
1214
]
1315
}
1416
},
15-
"postCreateCommand": "bash .devcontainer/post-create.sh",
17+
"postCreateCommand": "poetry install --no-root",
1618
"remoteUser": "vscode"
17-
}
19+
}

.devcontainer/post-create.sh

Lines changed: 0 additions & 27 deletions
This file was deleted.

campus_python/api/v1/submissions.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ def update(
173173

174174
def submit(self) -> None:
175175
"""Finalize/submit this submission (marks submitted_at timestamp)."""
176-
path = f"{self.make_path()}/submit"
176+
path = self.make_path("submit", end_slash=False)
177177
resp = self.client.post(path)
178178
resp.raise_for_status()
179179
return None

campus_python/api/v1/timetable.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,13 @@ def __getitem__(self, timetable_id: str) -> "Timetables.Timetable":
6262

6363
def get_current(self) -> str:
6464
"""Get the timetable ID of current timetable."""
65-
resp = self.client.get(self.make_path("current"))
65+
resp = self.client.get(self.make_path("current", end_slash=False))
6666
resp.raise_for_status()
6767
return resp.json()["value"]
6868

6969
def get_next(self) -> str:
7070
"""Get the timetable ID of next timetable."""
71-
resp = self.client.get(self.make_path("next"))
71+
resp = self.client.get(self.make_path("next", end_slash=False))
7272
resp.raise_for_status()
7373
return resp.json()["value"]
7474

@@ -79,7 +79,7 @@ def set_current(self, timetable_id: str) -> None:
7979
timetable_id: ID of the timetable to set as current
8080
"""
8181
resp = self.client.put(
82-
self.make_path("current"),
82+
self.make_path("current", end_slash=False),
8383
json={"value": timetable_id}
8484
)
8585
resp.raise_for_status()
@@ -91,7 +91,7 @@ def set_next(self, timetable_id: str) -> None:
9191
timetable_id: ID of the timetable to set as next
9292
"""
9393
resp = self.client.put(
94-
self.make_path("next"),
94+
self.make_path("next", end_slash=False),
9595
json={"value": timetable_id}
9696
)
9797
resp.raise_for_status()

campus_python/auth/v1/clients.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ def revoke(self) -> str:
6666
Returns:
6767
The newly generated client secret.
6868
"""
69-
resp = self.client.post(self.make_path("revoke"))
69+
resp = self.client.post(self.make_path("revoke", end_slash=False))
7070
# Raise error if status code is not 2XX or 3XX
7171
resp.raise_for_status()
7272
return resp.json()["secret"]
@@ -105,7 +105,7 @@ def grant(
105105
vault: str,
106106
permission: int,
107107
) -> JsonDict:
108-
resp = self.client.post(self.make_path("grant"), json={
108+
resp = self.client.post(self.make_path("grant", end_slash=False), json={
109109
"vault": vault,
110110
"permission": permission,
111111
})
@@ -118,7 +118,7 @@ def revoke(
118118
vault: str,
119119
permission: int,
120120
) -> JsonDict:
121-
resp = self.client.post(self.make_path("revoke"), json={
121+
resp = self.client.post(self.make_path("revoke", end_slash=False), json={
122122
"vault": vault,
123123
"permission": permission,
124124
})

campus_python/auth/v1/sessions.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def __getitem__(self, session_id: str) -> "CampusSessions.Session":
3232
def from_code(self, code: str) -> campus.model.AuthSession:
3333
"""Get a session using authorization code."""
3434
resp = self.client.post(
35-
self.make_path("authorization_code"),
35+
self.make_path("authorization_code", end_slash=False),
3636
json={"code": code}
3737
)
3838
resp.raise_for_status()
@@ -85,7 +85,7 @@ def sweep(self, at_time: datetime | str | None = None) -> int:
8585
json_data["at_time"] = schema.DateTime(at_time)
8686
case None:
8787
json_data["at_time"] = schema.DateTime.utcnow()
88-
resp = self.client.post(self.make_path("sweep"), json=json_data)
88+
resp = self.client.post(self.make_path("sweep", end_slash=False), json=json_data)
8989
resp.raise_for_status()
9090
return int(resp.json()["swept_count"])
9191

campus_python/auth/v1/users.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ class User(Resource):
4141
"""Single vault user resource."""
4242

4343
def activate(self) -> campus.model.User:
44-
resp = self.client.post(self.make_path("activate"))
44+
resp = self.client.post(self.make_path("activate", end_slash=False))
4545
resp.raise_for_status()
4646
return campus.model.User.from_resource(resp.json())
4747

campus_python/interface.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -90,16 +90,19 @@ def client(self) -> JsonClient:
9090
return self.root.client
9191
raise AttributeError(f"No client defined for {self}")
9292

93-
def make_path(self, part: str | None = None) -> str:
93+
def make_path(self, part: str | None = None, end_slash: bool = True) -> str:
9494
"""Create a full path for a resource collection.
9595
96-
Resource collection paths always end in a /.
96+
Args:
97+
part: Optional sub-resource or action path.
98+
end_slash: Whether to add a trailing slash (default: True for collections).
99+
100+
Returns:
101+
Full path for the resource collection or sub-resource.
97102
"""
98103
if part:
99-
return (
100-
f"/{self.root.make_path(self.path).strip(SLASH)}"
101-
f"/{part.strip(SLASH)}/"
102-
)
104+
base = f"/{self.root.make_path(self.path).strip(SLASH)}/{part.strip(SLASH)}"
105+
return f"{base}/" if end_slash else base
103106
else:
104107
return f"/{self.root.make_path(self.path).strip(SLASH)}/"
105108

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "campus-api-python"
3-
version = "0.1.60"
3+
version = "0.1.61"
44
description = "Campus API for Python projects"
55
authors = ["NYJC Computing <nyjc.computing@nyjc.edu.sg>"]
66

0 commit comments

Comments
 (0)