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

pre-release 3 (#244) #257

Closed
wants to merge 1 commit into from
Closed
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
61 changes: 45 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,55 @@
# UGent-5
# Apollo

## Rolverdeling
Apollo is an online submission platform where instructors can flexibly set requirements for
student submissions. These requirements can range from simple checks on the submitted
file structure to test scripts that run when a submission is made.

| Rol | Verantwoordelijke |
| ------------- | ------------- |
| Groepsleider | Marieke Sinnaeve |
| Technische lead | Bram Reyniers |
| Systeembeheerder | Xander Bil |
| Customer Relations Officer | Pieter Janin |
| Frontendbeheerder | Mattis Cauwel |
| Backendbeheerder | Dries Huybens |
| Documentatiebeheerder | Pieter Janin |
| Testbeheerder | Michaël Boelaert |
Students quickly receive feedback on their submission, allowing them to know if it meets
the project requirements.

This repository hosts the web application's source code. To use Apollo, visit https://sel2-5.ugent.be.

## Wiki

Informatie over de gebruikte technologieën, de gebruikershandleiding en meer kan je vinden in de [wiki](https://github.com/SELab-2/UGent-5/wiki).
Documentation, including a user manual for teachers, can be found in the
[Apollo wiki](https://github.com/SELab-2/UGent-5/wiki).

## For Developers

## Setup ontwikkelomgeving
Instructions for setting up the frontend development environment can be found
[here](frontend/README.md).

De instructies voor het opzetten van de ontwikkelomgeving van de frontend kan je [hier](frontend/README.md) vinden. De instructies voor de backend staan [hier](backend/REAMDE.md).
Instructions for the backend are located [here](backend/README.md).

## API

Geautomatiseerde clients kunnen interageren met de webapplicatie via de [API](https://sel2-5.ugent.be/api/docs).
Automated clients can interact with the web application via the [API](https://sel2-5.ugent.be/api/docs).

## Used tools and frameworks

### Database
- Database system: [PostgreSQL](https://www.postgresql.org/)
- Database migrations: [alembic](https://github.com/sqlalchemy/alembic).

### Backend
- Backend framework: [FastAPI](https://fastapi.tiangolo.com/)
- Database interface: [SQLAlchemy](https://www.sqlalchemy.org/)
- JSON-validation: [Pydantic](https://github.com/pydantic/pydantic)
- Test framework: [pytest](https://github.com/pytest-dev/pytest)

### Frontend
- Frontend framework: [Vue.js](https://vuejs.org/) (Composition API) + [TypeScript](https://www.typescriptlang.org/)
- Component library: [Vuetify](https://dev.vuetifyjs.com/en/)
- Test framework: [Vitest](https://vitest.dev/)

## The team

| | |
|------------------|---------------------------------------------------|
| Xander Bil | System Administrator |
| Michaël Boelaert | Test Manager |
| Mattis Cauwel | Frontend Manager |
| Dries Huybens | Backend Manager |
| Pieter Janin | Customer Relations Officer, Documentation Manager |
| Bram Reyniers | Technical Lead |
| Marieke Sinnaeve | Team Lead |
4 changes: 3 additions & 1 deletion backend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

```sh
# Create a python virtual environment
python -m venv venv
python3.12 -m venv venv
# Activate the environment
source venv/bin/activate
# Install dependencies
Expand Down Expand Up @@ -71,6 +71,8 @@ DATABASE_URI="postgresql://username:password@localhost:5432/dbname"
alembic upgrade head
```

You can find more info about alembic [here](alembic/README.md).

#### Managing the database
```sh
# Stop the database container
Expand Down
1 change: 0 additions & 1 deletion backend/alembic/README

This file was deleted.

43 changes: 43 additions & 0 deletions backend/alembic/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Alembic

From the docs:

> [Alembic](https://alembic.sqlalchemy.org/en/latest/) is a lightweight database
migration tool for usage with the [SQLAlchemy](https://www.sqlalchemy.org/)
Database Toolkit for Python.

It allows us to generate database schemas from Python SQLAlchemy code, found in each
`models.py` file.

## Usage

Here are some of the most commonly used commands you might need.

#### Automatically generate a revision script after modifying database models in Python:

```sh
alembic revision --autogenerate -m "my_revision_name"
```

Make sure to review the generated script in `alembic/versions`
and make adjustments if needed.

#### Run a migration: this will upgrade the database schema to the most recent revision.

```sh
alembic upgrade head
```

#### Undo the most recent revision:

```sh
alembic downgrade -1
```

#### Reset the database to its initial (empty) state:

```sh
alembic downgrade base
```

For more examples, see the [official Alembic tutorial](https://alembic.sqlalchemy.org/en/latest/tutorial.html).
35 changes: 35 additions & 0 deletions backend/alembic/versions/18fb90307213_project_requirements_fix.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
"""project_requirements_fix: fixes bug where project requirements would remain in the database after the parent
project would be deleted.

Revision ID: 18fb90307213
Revises: e0c97995e669
Create Date: 2024-05-04 15:42:43.114843

"""
from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision: str = '18fb90307213'
down_revision: Union[str, None] = 'e0c97995e669'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.alter_column('requirement', 'project_id',
existing_type=sa.INTEGER(),
nullable=False)
# ### end Alembic commands ###


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.alter_column('requirement', 'project_id',
existing_type=sa.INTEGER(),
nullable=True)
# ### end Alembic commands ###
31 changes: 31 additions & 0 deletions backend/alembic/versions/566f33fb161f_add_user_surname.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
"""add user surname

Revision ID: 566f33fb161f
Revises: 18fb90307213
Create Date: 2024-05-06 15:32:33.617263

"""
from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision: str = '566f33fb161f'
down_revision: Union[str, None] = '18fb90307213'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('website_user', sa.Column('surname', sa.String(),
nullable=False, server_default='SURNAME_DEFAULT'))
# ### end Alembic commands ###


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column('website_user', 'surname')
# ### end Alembic commands ###
44 changes: 44 additions & 0 deletions backend/alembic/versions/937c04aa37a1_add_group_num_column.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"""add group num column

Revision ID: 937c04aa37a1
Revises: 566f33fb161f
Create Date: 2024-05-18 18:09:30.734349

"""

from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision: str = "937c04aa37a1"
down_revision: Union[str, None] = "566f33fb161f"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.add_column(
"team", sa.Column("num", sa.Integer(), nullable=False, server_default="0")
)
op.drop_column("team", "team_name")
# ### end Alembic commands ###


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.add_column(
"team",
sa.Column(
"team_name",
sa.VARCHAR(),
autoincrement=False,
nullable=False,
server_default="DEFAULT_GROUP_NAME",
),
)
op.drop_column("team", "num")
# ### end Alembic commands ###
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
"""Add optional email to subject

Revision ID: e0c97995e669
Revises: d0e0719b1939
Create Date: 2024-05-01 14:23:11.789984

"""
from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql

# revision identifiers, used by Alembic.
revision: str = 'e0c97995e669'
down_revision: Union[str, None] = 'd0e0719b1939'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.alter_column('project', 'publish_date',
existing_type=postgresql.TIMESTAMP(timezone=True),
nullable=True,
existing_server_default=sa.text('CURRENT_TIMESTAMP'))
op.add_column('subject', sa.Column('email', sa.String(), nullable=True))
# ### end Alembic commands ###


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column('subject', 'email')
op.alter_column('project', 'publish_date',
existing_type=postgresql.TIMESTAMP(timezone=True),
nullable=False,
existing_server_default=sa.text('CURRENT_TIMESTAMP'))
# ### end Alembic commands ###
6 changes: 5 additions & 1 deletion backend/src/auth/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,19 @@ async def token(
if not user or not attributes:
raise UnAuthenticated(detail="Invalid CAS ticket")
# Create user if not exists
if not await user_service.get_by_id(db, attributes["uid"]):
resolved_user = await user_service.get_by_id(db, attributes["uid"])
if not resolved_user:
await user_service.create_user(
db,
UserCreate(
given_name=attributes["givenname"],
surname=attributes["surname"],
uid=attributes["uid"],
mail=attributes["mail"],
),
)
elif resolved_user.surname == 'SURNAME_DEFAULT':
resolved_user.surname = attributes["surname"]

# Create JWT token
jwt_token = create_jwt_token(attributes["uid"])
Expand Down
20 changes: 20 additions & 0 deletions backend/src/docker_tests/dependencies.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from typing import Generator, Any

import docker
from docker import DockerClient
from docker.errors import DockerException

from src.docker_tests.exceptions import DockerDeamonNotFound


def get_docker_client() -> Generator[DockerClient, Any, None]:
"""Creates docker client, which is closed afterwards"""
try:
client = docker.from_env()
except DockerException:
raise DockerDeamonNotFound()

try:
yield client
finally:
client.close()
Loading
Loading