Skip to content
Open
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
11 changes: 11 additions & 0 deletions .env-testing
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
API_MODE=prod
API_URL_PREFIX="/"
DB=relational
SQLITE_DB_PATH="/app/data/moh.sqlite"

THE_OG_UBIT="____"
THE_OG_PN=____

AUTOLAB_CLIENT_ID=____
AUTOLAB_SECRET=____
AUTOLAB_CALLBACK=____
2 changes: 1 addition & 1 deletion .github/workflows/formatter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [ "3.10", "3.11", "3.12" ]
python-version: [ "3.14" ]
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/pylint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [ "3.10", "3.11", "3.12" ]
python-version: [ "3.14" ]
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
Expand All @@ -20,4 +20,4 @@ jobs:
pip install -r ./api/utils.txt
- name: Analysing the code with pylint
run: |
pylint $(git ls-files '*.py')
pylint ./api
11 changes: 5 additions & 6 deletions .pylintrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
[MASTER]
init-hook='import sys; sys.path.append(".")'

[MAIN]

# Analyse import fallback blocks. This can be used to support both Python 2 and
Expand Down Expand Up @@ -104,10 +107,6 @@ recursive=no
# source root.
source-roots=

# When enabled, pylint would attempt to guess common misconfiguration and emit
# user-friendly hints instead of false-positive error messages.
suggestion-mode=yes

# Allow loading of arbitrary C extensions. Extensions are imported into the
# active Python interpreter and may run arbitrary code.
unsafe-load-any-extension=no
Expand Down Expand Up @@ -522,7 +521,7 @@ ignore-imports=yes
ignore-signatures=yes

# Minimum lines number of a similarity.
min-similarity-lines=4
min-similarity-lines=8


[SPELLING]
Expand Down Expand Up @@ -570,7 +569,7 @@ contextmanager-decorators=contextlib.contextmanager
# List of members which are set dynamically and missed by pylint inference
# system, and so shouldn't trigger E1101 when accessed. Python regular
# expressions are accepted.
generated-members=
generated-members=cursor

# Tells whether to warn about missing members when the owner of the attribute
# is inferred to be None.
Expand Down
73 changes: 44 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,44 +1,59 @@
# MakeOfficeHours

[![linting: pylint](https://img.shields.io/badge/linting-pylint-yellowgreen)](https://github.com/pylint-dev/pylint)
## Getting Started

# api/
A Flask API server that handles enqueuing and dequeuing students from the office hours queue.
See the relevant documentation for each component for development.

# Quick Started
1. You will first need to install all the development packages mainly use for, it will allow you to run tools locally for the project.
We have two Docker configurations that simulate a production sort of environment. The production setup will expect TLS certificates in the nginx directory. There's a shell script named `generate_testing_keys.sh` that can generate self-signed certificates.

The production setup will run the application on port 443.

To run the project in production:
```bash
pip install -r utils.txt
docker compose up --build
```

# Project structure
[//]: # (TODO: Going to do a markdown of a file structure here so that you can see the project structure)
The testing setup will run the application on port 3000.

# Development
For this project please use the following python version:
`"3.10", "3.11", "3.12"`

Running the development server:
To run the project in testing:
```bash
docker compose up api-development --build
docker compose -f compose-testing.yaml up --build
```

# Pylint
Project uses pylint to keep the code style organized.
These will use the respective environment files (`.env-api-prod` and `.env-testing`) for Autolab credentials and for creating the initial administrator account. Currently in production mode, accessing any user account (including the administrator account) require authentication via Autolab. Thus, you should probably only develop using either the testing configuration or by running everything locally. Testing exposes some additional endpoints (which are accessible from the frontend at `/dev-login`) with simple password authentication. This is not safe to use in production; anyone can claim any unclaimed user in the roster without proof.

You can run the Pylint on the api folder by doing the following
The `THE_OG_UBIT` and `THE_OG_PN` fields will add this account to the roster but will not create an account. You can create an account by logging into an Autolab account with a matching UBIT, or in testing hit the `/signup` endpoint (accessible from the frontend's `/dev-login` page).

```bash
pylint $(git ls-files '*.py')
```
Autolab integration is currently only used for authentication purposes. Since there isn't much need for further development on this front and since we have alternate authentication for testing purposes, testing API keys will generally not be distributed. Don't let this discourage you if you have ideas for further Autolab integration though, please talk to us on our Discord if you're interested!

# Formatter
Using the Black formatter https://github.com/psf/black
```bash
black $(git ls-files '*.py')
```
## Project Structure

### `/api`
A Flask API server and some utilities to run it locally and such.

### `/client`
A Vue frontend for the site.

### `/hardware`
Currently, a Python script for reading a specific card format to identify users and an example of a card payload. We may separate the card swipe hardware from the web application in the future. In that case, the relevant project will live here.

### `/nginx`
Some utilities for nginx, mainly the aforementioned shell script to generate testing keys for the Docker setup.

### `/tests`
Tests for the API server, which are not up to date.

## License

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

# Resource
Good resources to look at:
- https://flask.palletsprojects.com/en/stable/blueprints/
- https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-xv-a-better-application-structure
114 changes: 114 additions & 0 deletions api/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# MakeOfficeHours API

[![linting: pylint](https://img.shields.io/badge/linting-pylint-yellowgreen)](https://github.com/pylint-dev/pylint)

A Flask API server that handles enqueuing and dequeuing students from the office hours queue.

# Project Structure

### [/auth](./auth):

Routes and functions related to authentication. Authentication is independent of the roster; a user can be in the roster
but not have a sign-in. This just handles authenticating with Autolab, or password authentication in testing.

### [/config](./config):

Configuration for the Flask server.

### [/database](./database):

Home of the database interface and implementation. [`db.py`](./database/db.py) selects the implementation based on the
`DB` environment variable. This should probably always be set to "relational", as this is the only complete
implementation. If completed "mock" and "testing" may be useful for testing without a database, but the application is
fleshed out enough where this may not be necessary.

Anything outside this folder should import `db` from `db.py` and use the interface to interact with the database. If the
current functionality is not sufficient, it should be added to the database interface.

### [/queue](./queue):

Routes and functions related to the queue. This includes all endpoints relevant to enqueuing/dequeuing students.

Visits are created whenever a student is dequeued. Until one of the endpoints are hit that end a visit, TAs are
prevented from dequeuing and students are prevented from enqueuing.

### [/roster](./roster):

Routes and functions related to course management, mainly enrollments.

TAs can manage the roster but to ensure sensitive information is kept secret, they can only add students who only have
access to the queue endpoints. This is to ensure course instructors don't need to be concerned with the day-to-day
operations of the site (e.g. a student adds the course and comes to TA office hours but can't use the site, the TA
can just add them without having to go through the professor.)

The [controller](./roster/controller.py) defines two decorators that are used pretty extensively through the project
for permission checking: `@exact_level` and `@min_level`. It is **very** important that these decorators are below
`@blueprint.route`, as they are otherwise ignored.

### [/visits](./visits):

Routes and functions related to visits.

Visit records are sensitive information and should not be freely accessible to TAs. However, TAs can currently see
visits that they were
personally involved with for their own review.

### [/student_data_lookups](./student_data_lookups):

Currently, nothing. As this app grows to interact with other services, these interactions should live here.

### [/utils](./utils)

Mainly debug utilities. The `@debug_access_only` decorator is defined here. As with the roster decorators, these **must**
go below `@blueprint.route`. If used properly, it effectively disables this route in production. This is used for the
password authentication routes to ensure that in production only Autolab can be used to verify UBITs.


# Development

If you want to run the project locally, make sure you install the dependencies.

```bash
pip install -r requirements.txt
```

For this project please use python 3.14.

To run the API server locally, run
```bash
python -m api.run_local
```
from the **root directory** of the project. This will start the server in debug mode on port 5050.

# Utilities

You can install these utilities locally with:

```bash
pip install -r utils.txt
```

## Pylint

Project uses pylint to keep the code style organized.

You can run the Pylint on the api folder by doing the following

```bash
pylint $(git ls-files '*.py')
```

## Formatter

Using the Black formatter https://github.com/psf/black

```bash
black $(git ls-files '*.py')
```

# Resources

Good resources to look at:

- https://flask.palletsprojects.com/en/stable/blueprints/
- https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-xv-a-better-application-structure
Loading
Loading