Skip to content

Commit

Permalink
Add docstring
Browse files Browse the repository at this point in the history
  • Loading branch information
trungleduc committed Apr 16, 2024
1 parent 5e5611e commit 5bc8d30
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 17 deletions.
6 changes: 4 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,14 @@ jobs:
npm -g install configurable-http-proxy
- name: Run local build backend tests
working-directory: tljh_repo2docker/tests
run: |
python -m pytest tljh_repo2docker/tests/local_build --cov
python -m pytest local_build --cov
- name: Run binderhub build backend tests
working-directory: tljh_repo2docker/tests
run: |
python -m pytest tljh_repo2docker/tests/binderhub_build --cov
python -m pytest binderhub_build --cov
integration-tests:
name: Integration tests
Expand Down
5 changes: 4 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,13 @@ dependencies = [
"jupyter-repo2docker>=2024,<2025",
]
dynamic = ["version"]
license = { file = "LICENSE" }
license = {file = "LICENSE"}
name = "tljh-repo2docker"
readme = "README.md"

[project.scripts]
tljh_repo2docker_upgrade_db = "tljh_repo2docker.dbutil:main"

[project.entry-points.tljh]
tljh_repo2docker = "tljh_repo2docker"

Expand Down
14 changes: 14 additions & 0 deletions tljh_repo2docker/binderhub_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ class BinderHubBuildHandler(BaseHandler):
@web.authenticated
@require_admin_role
async def delete(self):
"""
Method to handle the deletion of a specific image.
Note:
- Only users with admin role or with `TLJH_R2D_ADMIN_SCOPE` scope can access it.
"""

data = self.get_json_body()
uid = UUID(data["name"])

Expand Down Expand Up @@ -55,6 +62,13 @@ async def delete(self):
@web.authenticated
@require_admin_role
async def post(self):
"""
Method to handle the creation of a new environment based on provided specifications.
As the build progresses, it updates the build log in the database and checks for completion.
Note:
- Only users with admin role or with `TLJH_R2D_ADMIN_SCOPE` scope can access it.
"""
data = self.get_json_body()

repo = data["repo"]
Expand Down
18 changes: 18 additions & 0 deletions tljh_repo2docker/binderhub_log.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,20 @@ class BinderHubLogsHandler(BaseHandler):
@web.authenticated
@require_admin_role
async def get(self, image_uid: str):
"""
Method to retrieve real-time status updates for a specific image build process.
This method sets the appropriate headers for Server-Sent Events (SSE) to enable streaming of data over HTTP.
It retrieves the database handlers and the image with the specified UID from the database.
Then, it continuously emits status updates over the stream until the build process is completed or times out.
Parameters:
- image_uid (str): The UID of the image for which real-time status updates are requested.
Raises:
- web.HTTPError: If the provided image UID is badly formed or if the requested image is not found.
"""

self.set_header("Content-Type", "text/event-stream")
self.set_header("Cache-Control", "no-cache")

Expand Down Expand Up @@ -64,6 +78,10 @@ async def get(self, image_uid: str):
break

async def _emit(self, msg):
"""
Asynchronous method to emit a message over a stream.
"""

try:
self.write(f"data: {json.dumps(msg)}\n\n")
await self.flush()
Expand Down
27 changes: 16 additions & 11 deletions tljh_repo2docker/dbutil.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ def check_db_revision(engine):
else:
raise Exception(
f"Found database schema version {alembic_revision} != {head}. "
"Backup your database and run `tljh_repo2docker upgrade-db`"
"Backup your database and run `tljh_repo2docker_upgrade_db`"
" to upgrade to the latest schema."
)

Expand Down Expand Up @@ -187,6 +187,16 @@ def async_to_sync_url(db_url: str) -> str:


def async_session_context_factory(async_db_url: str):
"""
Factory function to create an asynchronous session context manager.
Parameters:
- async_db_url (str): The URL for the asynchronous database connection.
Returns:
- AsyncContextManager[AsyncSession]: An asynchronous context manager that yields
an async session for database interactions within the context.
"""
async_engine = create_async_engine(async_db_url)
async_session_maker = async_sessionmaker(
async_engine,
Expand All @@ -204,14 +214,9 @@ async def get_async_session() -> AsyncGenerator[AsyncSession, None]:
return async_session_context


def main(args=None):
if args is None:
def main():
if len(sys.argv) > 1:
db_url = sys.argv[1]
alembic_args = sys.argv[2:]
# dumb option parsing, since we want to pass things through
# to subcommands
_alembic(db_url, alembic_args)


if __name__ == "__main__":
sys.exit(main())
upgrade(db_url)
else:
print("Missing database URL")
3 changes: 2 additions & 1 deletion tljh_repo2docker/tests/binderhub_build/test_builder.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import pytest
import sqlalchemy as sa
from aiodocker import Docker, DockerError

import asyncio
from tljh_repo2docker.database.model import DockerImageSQL

from ..utils import add_environment, remove_environment, wait_for_image
Expand All @@ -20,6 +20,7 @@ async def test_add_environment(
assert uid is not None

await wait_for_image(image_name=generated_image_name)
await asyncio.sleep(3)
images_db = db_session.execute(sa.select(DockerImageSQL)).scalars().first()
assert images_db.name == generated_image_name
assert images_db.image_meta["display_name"] == name
Expand Down
4 changes: 2 additions & 2 deletions tljh_repo2docker/tests/binderhub_build/test_images.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import pytest
from jupyterhub.tests.utils import get_page

import asyncio
from ..utils import add_environment, get_service_page, wait_for_image


Expand Down Expand Up @@ -45,7 +45,7 @@ async def test_spawn_page(app, minimal_repo, image_name, generated_image_name):
)
assert r.status_code == 200
await wait_for_image(image_name=generated_image_name)

await asyncio.sleep(3)
# the environment should be on the page
r = await get_page(
"services/tljh_repo2docker/environments",
Expand Down

0 comments on commit 5bc8d30

Please sign in to comment.