Skip to content

aeecleclair/Hyperion

Repository files navigation

Hyperion

codecov

Presentation

Hyperion is the API of an open-source project launched by ÉCLAIR, the computer science association of Ecole Centrale de Lyon. This project aims to provide students of business and engineering schools a digital tool to simplify the association process. In a way, we could say that Hyperion is trying to create a social network for school associations.

The structure of this project is modular. Hyperion has a core that performs vital functions (authentication, database migration, authorization, etc). The other functions of Hyperion are realized in what we call modules. You can contribute to the project by adding modules if you wish.

1. Creating a virtual environment for Python 3.14

Windows

Create the virtual environment

You need to be in Hyperion main folder

py -3.14 -m venv .venv

If you get an error saying roughly:

because the execution of scripts is disabled on this system. Please see "get-help about_signing" for more details.

Then in a Powershell, run this to allow scripts executions for your user:

Set-ExecutionPolicy Unrestricted -Scope CurrentUser

Activate it

.\.venv\Scripts\activate

macOS (using Pyenv)

Install Pyenv

brew install pyenv
brew install pyenv-virtualenv

Edit ~/.zhsrc and add at the end of the file :

eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"

Create the virtual environment

pyenv virtualenv 3.14.2 hyperion

Activate it

pyenv activate hyperion

2. Install dependencies

About Jellyfish and Rust (Windows only)

If you don't have Rust installed on your Windows PC or don't want to install it, decrease the version of jellyfish to 0.10.0 in the requirements.txt file:

jellyfish==0.10.0                    # String Matching

About Weasyprint and Pango

Follow the installation steps at https://doc.courtbouillon.org/weasyprint/stable/first_steps.html#installation.

For Windows, the best way is through MSYS2, Mac users can simply install using Homebrew.

Install dependencies (for real)

Install the dependencies you'll need using pip (the common requirements are included in the development requirements):

pip install -r requirements-dev.txt

If you changed the version of Jellyfish, don't forget to set it back:

jellyfish==1.0.4                    # String Matching

If you need to remove all modules from your virtual environnement, delete your .venv folder.

3. Install and configure a database

Choose either SQLite or PostgreSQL.

SQLite

Advantages

It is a binary. This means:

  • SQLite is lightweight
  • It is directly understood by your machine, no special configuration is needed.

Disadvantages

Being so light, it does not support some features nowadays common for relational databases:

  • Drop your database on every migration: Alembic uses features incompatible with SQLite

Installation and configuration

There is nothing to do, it works out of the box.

PostgreSQL

Advantages

Its advantages are many:

  • Very powerful database: it supports all the features you'll ever need.
  • Used in production for Hyperion.
  • Widely used in production in enterprise-grade services: useful competence on your résumé.
  • Supports migrations with Alembic.
  • A powerful CLI tool.

Disadvantages

None (not so heavy, configuration not so hard).

Configuration

Without Docker: native binaries
  1. Download the installer: https://www.enterprisedb.com/downloads/postgres-postgresql-downloads
  2. Launch it and trust the wizard
    • Keep the default folders and ports, install it all, etc...
    • ...but put a concise password you'd remember, choose your language
    • Don't use the "Stack Builder" (not needed)
  3. On Windows: in your path, add C:\Program Files\PostgreSQL\17\bin and C:\Program Files\PostgreSQL\17\lib (if you installed Postgres 17 in that location)
  4. Create a database named hyperion
psql -U postgres -c "create database hyperion;"

[!TIP] SQL keywords are case-insensitive by convention. No need to write CREATE DATABASE hyperion;

Now your Hyperion database can be explored by hand (as the postgres user, using your password you chose) with:

psql -U postgres -d hyperion

then running SQL or Postgres commands in this shell, or

psql -U postgres -d hyperion -c "select firstname from core_user;"
With Docker

[!WARNING] Work in progress

services:
  hyperion-db:
    image: postgres:15.1
    container_name: hyperion-db
    restart: unless-stopped
    healthcheck:
      test: [ "CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}" ]
      interval: 5s
      timeout: 5s
      retries: 5
    environment:
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_HOST: ${POSTGRES_HOST}
      POSTGRES_DB: ${POSTGRES_DB}
      PGTZ: ${POSTGRES_TZ}
    ports:
      - 5432:5432
    volumes:
      - ./hyperion-db:/var/lib/postgresql/data

4. Complete the dotenv (.env) and the config.yaml

Important

Copy the .env.template file in a new .env file, likewise copy config.template.yaml in a new config.yaml.

cp .env.template .env && cp config.template.yaml config.yaml

Tip

These template files were carefully crafted to work for you with minimal personal changes to bring, and some preconfigured services.

For later reference, these settings are documented in app/core/config.py. Check this file to know what can and should be set using these two files.

The .env file

The .env contains environment variables which can be accessed by the OS to convey them to other services that need them, such as the database.

With SQLite

Again there's nothing to do.

With PostgreSQL

Set your user, password, host and db.

For instance, with the installer you should have something like:

POSTGRES_USER="postgres"
POSTGRES_PASSWORD=""
POSTGRES_HOST="localhost"
POSTGRES_DB="hyperion"

While with Docker you should have rather something like:

POSTGRES_USER="hyperion"
POSTGRES_PASSWORD=""
POSTGRES_HOST="hyperion-db" # Should be set to the name of the postgres container
POSTGRES_DB="hyperion"

The config.yaml file

The config.yaml contains environment variables that are internal to the Python runtime because they are only used in the Python code.

  1. ACCESS_TOKEN_SECRET_KEY and RSA_PRIVATE_PEM_STRING: An example of each is provided. You can generate your own if you want, or just change a couple characters in the examples, or deliberately leave it as it is.
  2. SQLITE_DB: tells Hyperion whether to use SQLite or PostgreSQL.
    • If you use SQLite: this field should be a (relative) filename, by default we named it app.db, you can change this name. Hyperion will create this file for you and use it as the database. Any PostgreSQL-related configuration will be ignored.
    • If you use PostgreSQL: empty this field. Hyperion will fallback to PostgreSQL settings.
  3. USE_FACTORIES: True by default, factories seed your database, if empty, with mocked data. This is useful on SQLite to repopulate your new database after dropping the previous one, of to create automatically your own user with admin privileges (see FACTORIES_DEMO_USERS below).
  4. FACTORIES_DEMO_USERS: Replace the first user's data with yours. These future users will be created automatically when launching Hyperion with an empty database. Plus, your user will be there with your password and be admin out of the box.

5. Launch the API

Warning

Beforehand, check that your venv is activated.

Using VS Code

  1. In the activity bar (the leftmost part), click the Run and Debug icon (the play button).
  2. Click the green play button.

Check that your Hyperion instance is up and running by navigating to http://localhost:8000/information.

Using the command-line interface

fastapi dev

Check that your Hyperion instance is up and running by navigating to http://localhost:8000/information.

6. Create your own user (if not yet the case using factories)

There are at least 5 distinct ways to do so outside the use of factories, ranked here from easiest (~GUI) to hardest (~CLI).

Important

Using factories is the recommended way. All others methods are legacy and kept here for historical reasons (excepted using Titan, which is the way users create their account in production). Feel free to create other users other ways for learning purposes.

Note that registration and activation are distinct steps when calling calls to the API, so for fun you may register one way and activate your account another way (if you create your user directly in database, this distinction is not relevant).

Using CalypSSO

Registering your account

Go to http://localhost:8000/calypsso/register and type a valid email address to register (start the creation of) your account.

Activating your account

Go back to the shell running your Hyperion instance, in the logs look for a link looking like http://localhost:3000/calypsso/activate?activation_token=12345. Open it and activate (end the creation of) your account.

Using Titan

  1. Click "Se connecter" on the login page: you land CalypSSO's login page.
  2. Click "Créer un compte" and create your account using CalypSSO as above.

Using the API through the swagger

Registering your account

  1. Go to http://localhost:8000/docs: this is called the swagger, a web interface to interact with the API, it is a layer on top of the "automatic documentation" (the OpenAPI specification) generated by FastAPI at http://localhost:8000/openapi.json.
  2. Search /users/create.
  3. Open it, click "Try it out".
  4. Fill in your email address, and click "Execute".

Activating your account

  1. Go back to the shell running your Hyperion instance, in the logs look for a link looking like http://localhost:3000/calypsso/activate?activation_token=12345.
  2. Copy this activation token.
  3. Go again on the swagger and search /users/activate.
  4. Open it, click "Try it out".
  5. Fill in your information, using the activation_token you copied (click "Schema" next to "Edit Value" so see what fields are optional), and click "Execute".

Using the API in command line

[!TIP] On Windows, curl is different. To get the same results as on Linux and MacOS:

  • either replace curl with curl.exe
  • or run the curl commands below in a bash (using WSL or using Git Bash)

Registering your account

curl --json '{"email": "prenom.nom@etu.ec-lyon.fr"}' http://localhost:8000/users/create

Activating your account

  1. Go back to the shell running your Hyperion instance, in the logs look for a link looking like http://localhost:3000/calypsso/activate?activation_token=12345.
  2. Copy this activation token.
  3. Use this activation_token in:
curl --json '{
    "name": "<Name>",
    "firstname": "<Firstname>",
    "nickname": "<Nickname>",
    "activation_token": "<ActivationToken>",
    "password": "<Password>",
    "birthday": "<2019-08-24>",
    "phone": "<Phone>",
    "promo": 0,
    "floor": ""
}' http://localhost:8000/users/activate

Using a database client in command line

[!WARNING] Work in progress

  1. Open a shell connected to your database for Hyperion
    • PostgreSQL: see above, generally psql -U <username> -d hyperion.
    • SQLite: ...
  2. Insert your own user into the users' table (for centrale_lyon school, generate your own user UUID and salted hash, feel free to add insert values into nullable columns) :
insert into core_user (id, firstname, name, nickname, email, password_hash, school_id, account_type) values ('01234567-89ab-cdef-0123-456789abcdef', '<Fistname>', '<Name>', '<Nickname>', '<email>', '$2b$<saltlength>$<yourpasswordsaltedhash>', 'd9772da7-1142-4002-8b86-b694b431dfed', 'student');

7. Make your user admin (if not yet the case using factories)

Important

Again, using factories is the recommended way.

If there is exactly one user in the database

Then you can make it admin using the following command:

curl -X POST http://localhost:8000/users/make-admin

Using a database client in command line

Warning

Work in progress

  1. Open a shell connected to your database for Hyperion
    • PostgreSQL: see above, generally psql -U <username> -d hyperion.
    • SQLite: ...
  2. Get the UUID for your own user, then insert it and the UUID for the admin grouptype in the memberships table :
insert into core_membership (user_id, group_id) values ('<Your user_id>', '0a25cb76-4b63-4fd3-b939-da6d9feabf28');

Beyond initial configuration

Install Docker or an equivalent

Install docker and the compose plugin (https://docs.docker.com/compose/install/)

docker-compose.yaml includes the minimal settings required to run Hyperion using docker compose.

During dev, docker-compose-dev.yaml can be used to run the database, the redis server etc... If you really want to run the project without docker, you can do it but you will have to install the database, redis, etc ... yourself or disable corresponding features in the .env file (which is not recommended).

Linting and formating

To lint and format, we currently use Ruff. We also use Mypy for the type checking.

Before each PR or git push you will need to run ruff check --fix && ruff format in order to format/lint your code and mypy . in order to verify that there is no type mismatch.

Use Alembic migrations

See migrations README

[!WARNING] On SQLite databases, you have to drop the database and recreate it to apply the new DDL.

OpenAPI specification

API endpoints are parsed following the OpenAPI specifications at http://127.0.0.1:8000/openapi.json.

A Swagger UI is available at http://127.0.0.1:8000/docs. For authentication to work, a valid AUTH_CLIENT must be defined in the .env, with http://127.0.0.1:8000/docs/oauth2-redirect as the redirect URI, and scope=API must be added to the authentication request.

Configure Firebase notifications

Hyperion support push notification using Firebase Messaging service.

To enable the service:

  1. Add USE_FIREBASE=true to dotenv file
  2. Create a service account on Firebase console:
    1. Go to Google cloud, IAM and administration, Service account and add a new Service Account with Messaging API capabilities.
    2. Choose Manage keys and create a new JSON key.
    3. Rename the file firebase.json and add it at Hyperion root

Use websocket

When using multiples workers, a Redis server must be configured to broadcast messages between workers.

Google API usage

Hyperion can use Google API to run App Script and upload files to Google Drive. See app/core/google_api/README.md for more information.


Hyperion deployment

For production we encourage to use multiple Uvicorn workers. You can use our docker image and docker-compose file files to run Hyperion with Unicorn.

You should use our init file to ensure that database initialization and migrations are only run once.

About

API for ÉCLAIR's platform

Topics

Resources

License

Security policy

Stars

Watchers

Forks

Contributors 35

Languages