-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
196 additions
and
78 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,14 @@ | ||
# Please provided relative paths with ./ or things can break :) | ||
|
||
export SESSION_DIR="./data/flask_sessions/" | ||
export SESSION_LIFETIME="3600" | ||
SESSION_DIR="./data/flask_sessions/" | ||
SESSION_LIFETIME="3600" | ||
|
||
export DATABASE_PATH="./data/hackerschool.sqlite3" | ||
export ROLES_PATH="./data/roles.json" | ||
export PHOTOS_DIR="./data/photos/" | ||
DATABASE_PATH="./data/hackerschool.sqlite3" | ||
ROLES_PATH="./data/roles.json" | ||
PHOTOS_DIR="./data/photos/" | ||
|
||
export LOG_LEVEL="INFO" | ||
export LOGS_PATH="./data/logs/app.log" | ||
LOG_LEVEL="INFO" | ||
LOGS_PATH="./data/logs/app.log" | ||
|
||
export ADMIN_USERNAME="admin" | ||
export ADMIN_PASSWORD="admin" | ||
ADMIN_USERNAME="admin" | ||
ADMIN_PASSWORD="admin" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
|
||
name: Python application | ||
name: Unittests | ||
|
||
on: | ||
push: | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,93 +1,208 @@ | ||
# HS-API | ||
![unittests](https://github.com/HackerSchool/HS-API/actions/workflows/unittests.yml/badge.svg) | ||
|
||
## Intro | ||
The HackerSchool API is an integrated database that accepts requests from the Internet via the Flask framework. Its purpose is to ease the resource management process for development teams and Human Resources. This system allows the retrieval member data, their projects, contributions, and other HackerSchool assets. | ||
*** | ||
The HackerSchool API is an integrated database that accepts requests from the Internet via the Flask framework. Its purpose is to ease the resource management process for development teams and Human Resources. | ||
|
||
## Running | ||
Before you can use the container, you'll need to set up the SQLite database and create some directories. If you already have all application-related directories created and `.env` properly set up, you can skip to Step 2. | ||
--- | ||
|
||
## Table of Contents | ||
|
||
- [Features](#features) | ||
- [Technologies](#extensions) | ||
- [Setup](#setup) | ||
- [Environment Variables](#environment-variables) | ||
- [Project Structure](#project-structure) | ||
- [Testing](#testing) | ||
- [Endpoints](#endpoints) | ||
- [Issues and To-do](#issues-and-to-do) | ||
- [Other](#other) | ||
|
||
## Features | ||
|
||
- User authentication and role based authorization | ||
- CRUD operations for members and projects | ||
- Members and projects photos fetch and upload | ||
|
||
### Step 1 | ||
You'll need Flask to create the database and related storage directories that will be mounted onto the container. | ||
Adjust and source the `.env` to specify where you want to store application data on your host, and to include the admin user credentials (if you don't you won't have access to any endpoint, you can create a new user later and delete the admin one). | ||
```sh | ||
## Technologies | ||
- Web App Framework - [Flask](https://github.com/pallets/flask) | ||
- Session management - [Flask-Session](https://github.com/pallets-eco/flask-session/) | ||
- ORM - [Flask-SQLAlchemy](https://github.com/pallets-eco/flask-sqlalchemy/) | ||
- Database - [sqlite3](https://docs.python.org/3/library/sqlite3.html) | ||
<!-- - CORS - [Flask-Cors]() --> | ||
|
||
## Setup | ||
### Prerequisites | ||
Make sure you have the following installed: | ||
- Python 3.x | ||
- pip | ||
|
||
### Installation | ||
1. **Clone the repository**: | ||
```bash | ||
git clone [email protected]:HackerSchool/HS-API.git | ||
cd HS-API | ||
``` | ||
2. **Create a virtual environment**: | ||
```bash | ||
python -m venv .venv | ||
source .venv/bin/activate | ||
source .env | ||
``` | ||
3. **Install dependencies**: | ||
```bash | ||
pip install -r requirements.txt | ||
flask db-init | ||
``` | ||
4. **Setup environment variables**: Create a `.env` file and add any necessary environment variables (see [Environment Variables](#environment-variables) section). | ||
5. **Setup the database and create an admin user**: | ||
```bash | ||
flask init-db | ||
flask create-admin | ||
``` | ||
6. **Run the application**: | ||
```bash | ||
flask run --debug | ||
``` | ||
|
||
### Step 2 | ||
If you are not planning to develop, you can get rid of Flask, you won't need it anymore! | ||
To start the container simply run `docker compose up`. | ||
|
||
## Development | ||
For development use the Flask built in development server in a virtual environment. Don't forget to also source `.env` and initiailze the db if necessary on development mode! | ||
```sh | ||
cp .env.example .env | ||
python -m venv .venv | ||
source .venv/bin/activate | ||
pip install -r requirements.txt | ||
flask run --debug | ||
### Docker Setup (Optional) | ||
1. **Create all application-data folders**: `docker compose` will mount the database and required folders into the container. For this you need to initialize the database, please refer to the [installation steps 1 to 5](#installation) to set this up. | ||
1. **Build the docker image**: | ||
```bash | ||
docker compose build | ||
``` | ||
2. **Run the application (with gunicorn)**: | ||
```bash | ||
docker compose up | ||
``` | ||
|
||
## Environment Variables | ||
**TLDR**: You can just `cp .env.example .env` to get all default environment variables ready. | ||
|
||
- `SESSION_DIR`: Where to store session files (defaults to `data/flask_sessions/`) | ||
- `SESSION_LIFETIME`: How long a session should last in seconds (defaults to 3 hours) | ||
|
||
- `DATABASE_PATH`: Path to the `sqlite3` database file (defaults to `data/hackerschool.sqlite3`) | ||
- `ROLES_PATH`: Path to the roles configuration json file (defaults to `data/roles.json`) | ||
- `PHOTOS_DIR`: Path to the folder where user and project images will be stored (defaults to `data/photos/`) | ||
|
||
- `LOG_LEVEL`: Log level (defaults to INFO) | ||
- `LOGS_PATH` Path to logs file (deault to stdout) | ||
|
||
These will only be necessary if you'll be using the `flask create-admin` command | ||
- `ADMIN_USERNAME` Admin username | ||
- `ADMIN_PASSWORD` Admin password | ||
|
||
|
||
**Note**: If you use `docker compose` you will either need the `.env` file or environment variables set (no default values will be used) because `docker compose` will use use them to mount the correct volumes. | ||
|
||
## Project Structure | ||
The project follows a layered architecture with a controller, service and models layer. | ||
```txt | ||
+-------------+ | ||
| Controller | | ||
+-------------+ | ||
^ | ||
| | ||
| | ||
+-------------+ | ||
| Service | | ||
+-------------+ | ||
^ ^ | ||
| | | ||
| +---------------------+ | ||
| | | ||
+-------------+ +------------------+ | ||
| Models | | Other Handlers | (e.g, logos handler in filesystem) | ||
+-------------+ +------------------+ | ||
``` | ||
The structure is based on the Flask [factory extension pattern](https://flask.palletsprojects.com/en/stable/patterns/appfactories/#factories-extensions). | ||
```txt | ||
├── app/ | ||
│ ├── api/ # controller layer | ||
│ │ | ||
│ ├── services/ # service layer | ||
│ │ | ||
│ ├── models/ # database models layer | ||
│ │ | ||
│ ├── commands/ # commands definitions (like init-db, create-admin) | ||
│ │ | ||
│ ├── logos/ # logos extension | ||
│ │ | ||
│ ├── roles/ # roles extension | ||
│ │ | ||
│ ├── config.py # flask configuration variables | ||
│ │ | ||
│ ├── extensions.py # loading extensions | ||
│ │ | ||
│ └── __init__.py # entrypoint with flask app factory | ||
│ | ||
├── data/ # application files | ||
│ └── roles.json # roles configuration file | ||
│ | ||
└── tests/ # components tests | ||
├── models/ | ||
│ | ||
└── roles/ | ||
``` | ||
--- | ||
## Testing | ||
To test run the following in the root directory of the repository: | ||
```bash | ||
python -m unittests -s discover | ||
``` | ||
|
||
## Endpoints | ||
`Content-Type` refers to the response type for `GET` requests and request type for `POST`, `PUT` and `DELETE` requests. | ||
`-` refers to unused. | ||
|
||
### Auth | ||
```txt | ||
Endpoints: | ||
- POST /login Login | ||
- GET /logout Logout | ||
``` | ||
|
||
| Method | URL | Content-Type | Description | | ||
|----------|---------------|--------------|---------------------------------| | ||
| `POST` | `/login` | `json` | Login and set cookie session ID | | ||
| `GET` | `/logout` | `json` | Logout and end session | | ||
|
||
### Members | ||
```txt | ||
Endpoints: | ||
- GET /members Get all members | ||
- POST /members Create member | ||
- GET /members/{username} Get member | ||
- PUT /members/{username} Update member | ||
- DELETE /members/{username} Delete member | ||
- PUT /members/{username}/edit_password Change password | ||
- POST /members/{username}/{proj_name} Add project to member | ||
- DELETE /members/{username}/{proj_name} Remove project from member | ||
- GET /members/{username}/projects Get member projects | ||
- GET /members/{username}/logo Get member logo | ||
- PUT /members/{username}/logo Upload member logo | ||
- DELETE /members/{username}/logo Delete member logo | ||
- GET /members/{username}/roles Get member roles | ||
- PUT /members/{username}/roles Add member roles | ||
- DELETE /members/{username}/roles Delete member roles | ||
``` | ||
|
||
| Method | URL | Content-Type | Description | | ||
|----------|-----------------------------------------|--------------|-----------------------------------------------------------| | ||
| `GET` | `/members` | `json` | Get a list of all members | | ||
| `POST` | `/members` | `json` | Create a new member | | ||
| `GET` | `/members/{username}` | `json` | Get details of a specific member by username | | ||
| `PUT` | `/members/{username}` | `json` | Update member details by username | | ||
| `DELETE` | `/members/{username}` | `-` | Delete a member by username | | ||
| `PUT` | `/members/{username}/edit_password` | `json` | Change member password by username | | ||
| `POST` | `/members/{username}/{proj_name}` | `json` | Add a project to the member's list | | ||
| `DELETE` | `/members/{username}/{proj_name}` | `-` | Remove a project from the member's list of projects | | ||
| `GET` | `/members/{username}/projects` | `json` | Get a list of all projects a member is associated with | | ||
| `GET` | `/members/{username}/logo` | `-` | Get member's profile logo | | ||
| `PUT` | `/members/{username}/logo` | `multipart/form-data`| Upload or update member's logo | | ||
| `DELETE` | `/members/{username}/logo` | `-` | Delete member's logo | | ||
| `GET` | `/members/{username}/roles` | `json` | Get roles assigned to a member | | ||
| `PUT` | `/members/{username}/roles` | `json` | Add roles to the member | | ||
| `DELETE` | `/members/{username}/roles` | `json` | Remove roles from the member | ||
|
||
### Projects | ||
```txt | ||
Endpoints: | ||
- GET /projects Get all projects | ||
- POST /projects Create project | ||
- GET /projects/{proj_name} Get project | ||
- PUT /projects/{proj_name} Update project | ||
- DELETE /projects/{proj_name} Delete project | ||
- POST /projects/{proj_name}/{username} Add project to member | ||
- DELETE /projects/{proj_name}/{username} Remove project from member | ||
- GET /projects/{proj_name}/members Get project members | ||
- GET /projects/{proj_name}/logo Get project logo | ||
- PUT /projects/{proj_name}/logo Upload project logo | ||
- DELETE /projects/{proj_name}/logo Delete project logo | ||
``` | ||
### Login | ||
Authentication is session based. To login and start a session, use the `/login` endpoint. | ||
|
||
--- | ||
## What now? | ||
The next step is creating a frontend. | ||
| Method | URL | Content-Type |Description | | ||
|--------|-------------------------------------------|--------------|-----------------------------------------------------| | ||
| `GET` | `/projects` |`json` | Get a list of all projects | | ||
| `POST` | `/projects` |`json` | Create a new project | | ||
| `GET` | `/projects/{proj_name}` |`json` | Get details of a specific project by project name | | ||
| `PUT` | `/projects/{proj_name}` |`json` | Update project details by project name | | ||
| `DELETE` | `/projects/{proj_name}` |`-` | Delete a project by project name | | ||
| `POST` | `/projects/{proj_name}/{username}` |`json` | Add a member to the project | | ||
| `DELETE` | `/projects/{proj_name}/{username}` |`-` | Remove a member from the project | | ||
| `GET` | `/projects/{proj_name}/members` |`json` | Get a list of all members associated with a project | | ||
| `GET` | `/projects/{proj_name}/logo` |`json` | Get project logo | | ||
| `PUT` | `/projects/{proj_name}/logo` |`multipart/form-data` | Upload or update project logo | | ||
| `DELETE` | `/projects/{proj_name}/logo` |`-` | Delete project logo | | ||
|
||
Known issues can be found [here](https://github.com/HackerSchool/HS-API/issues/5), and a TODO list [here](https://github.com/HackerSchool/HS-API/issues/7). | ||
## Issues and To-Do | ||
Known issues can be found [here](https://github.com/HackerSchool/HS-API/issues/5), and a to-do list [here](https://github.com/HackerSchool/HS-API/issues/7). | ||
|
||
Contributions are welcomed! | ||
## Other | ||
- A [frontend](https://github.com/HackerSchool/HS-WebApp) application is currently under development. | ||
|
||
- A CLI for the API is available [here](https://github.com/HackerSchool/hs-cli). | ||
|
||
## CLI | ||
A CLI for the API is available [here](https://github.com/HackerSchool/hs-cli). | ||
Contributions are welcomed! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters