Skip to content
Snippets Groups Projects
Commit b4947d0a authored by Victor Löfgren's avatar Victor Löfgren
Browse files

Resolve "Add automatic documentation generation"

parent feaca508
No related branches found
No related tags found
1 merge request!113Resolve "Add automatic documentation generation"
Pipeline #42993 passed
Showing
with 255 additions and 0 deletions
http_codes
==========
.. automodule:: app.core.http_codes
parsers
=======
.. automodule:: app.core.parsers
:members:
:undoc-members:
:show-inheritance:
rich schemas
============
.. automodule:: app.core.rich_schemas
core
====
.. automodule:: app.core
:members:
:undoc-members:
:show-inheritance:
Submodules
----------
.. toctree::
:maxdepth: 4
app.core.codes
app.core.dto
app.core.files
app.core.http_codes
app.core.parsers
app.core.rich_schemas
app.core.schemas
app.core.sockets
schemas
=======
.. automodule:: app.core.schemas
sockets
=======
.. automodule:: app.core.sockets
:members:
:undoc-members:
:show-inheritance:
app.database.controller.add module
==================================
.. automodule:: app.database.controller.add
:members:
:undoc-members:
:show-inheritance:
app.database.controller.copy module
===================================
.. automodule:: app.database.controller.copy
:members:
:undoc-members:
:show-inheritance:
app.database.controller.delete module
=====================================
.. automodule:: app.database.controller.delete
:members:
:undoc-members:
:show-inheritance:
app.database.controller.edit module
===================================
.. automodule:: app.database.controller.edit
:members:
:undoc-members:
:show-inheritance:
app.database.controller.get module
==================================
.. automodule:: app.database.controller.get
:members:
:undoc-members:
:show-inheritance:
app.database.controller package
===============================
.. automodule:: app.database.controller
:members:
:undoc-members:
:show-inheritance:
Submodules
----------
.. toctree::
:maxdepth: 4
app.database.controller.add
app.database.controller.copy
app.database.controller.delete
app.database.controller.edit
app.database.controller.get
app.database.controller.search
app.database.controller.utils
app.database.controller.search module
=====================================
.. automodule:: app.database.controller.search
:members:
:undoc-members:
:show-inheritance:
app.database.controller.utils module
====================================
.. automodule:: app.database.controller.utils
:members:
:undoc-members:
:show-inheritance:
app.database.models module
==========================
.. automodule:: app.database.models
:members:
:undoc-members:
:show-inheritance:
app.database package
====================
.. automodule:: app.database
:members:
:undoc-members:
:show-inheritance:
Subpackages
-----------
.. toctree::
:maxdepth: 4
app.database.controller
Submodules
----------
.. toctree::
:maxdepth: 4
app.database.models
app.database.types
app.database.types module
=========================
.. automodule:: app.database.types
:members:
:undoc-members:
:show-inheritance:
app
===
.. automodule:: app
:members: create_app
:undoc-members:
:show-inheritance:
Subpackages
-----------
.. toctree::
:maxdepth: 1
app.apis
app.core
app.database
# Server
The backend is mainly responsible for storing every user and all competitions.
It also needs to make sure the every API call and socket event is authorized.
The server is written in Python together with the micro-framework Flask.
## Overview
The server has two main responsibilites.
The first is to handle API calls from the client to store, update and delete information, such as competitions or users.
It also needs to make sure that only authorized people can access these.
The other is to sync slides, timer and answers between clients in an active competition.
Both of these will be described in more detail below.
## Receiving API calls
An API call is a way the client can communicates with the server.
When a request is received the server begins by authorizing it (making sure the person sending the request is allowed to access the route).
After that it makes sure that it got all information in the request it needed.
The server will then do the thing the client requested.
And finally it will need to generate repsonse, usually in the form of an object from the database.
All of these steps are described in more detail below.
### Routes
Each route which is possible to call is specified in the files in the `app/apis/` folder.
All available routes can also be seen by navigating to `localhost:5000` after starting the server.
### Authorization
When the server receives an API call the first thing it does is to authorize it.
The authorization is done using JSON Web Tokens (JWT) by comparing the contents of them with what is expected.
Whenever a client logs into an account or joins a competition, it is given a JWT generated by the server, and the client will need to use this token in every subsequent request sent to the server to authenticate itself.
What authorization to be done on the server is specified by the `@protect_route()` decorator.
This decorator specifies who is allowed to access this route, which can either be users with specific roles, or people who have joined competitions with specific views.
If the route is not decorated everyone is allowed to access it, the only routes currently like that is logging in as a user and joining a competition, by necessity.
### Parsing request
After the request is authorized the server will need to parse contents of the request.
The parsing is done with [reqparse](https://flask-restx.readthedocs.io/en/latest/parsing.html) from RestX (this module is deprecated and should be replaced).
Each API call expects different parameters in different places and this is specificied in each of the files in `app/apis/` folder, together with the route.
### Handling request
After the request has been authorized and parsed the server needs to act on the request.
What the server does of course depends on the route and given arguments, but it usually gets, edits or deletes something from the database.
The server uses an SQL database and interfaces to it via SQLAlchemy.
Everything related to the database is located in the `app/database/` folder.
### Responding
When the server is done handling the request it usually responds with an item from the database.
Converting a database object to json is done with [Marsmallow](https://marshmallow.readthedocs.io/en/stable/).
How to do this conversion is specified in two files in in the folder `app/core/`.
The file `schemas.py` just converts a record in the database field by field.
The file `rich_schemas.py` on the other hand converts an `id` in one table to an entire object in the another table, thus the name rich.
In this way, for example, an entire competition with it's teams, codes, slides and the slides' questions and components can be returned in a single API call.
## Active competitions
Slides, timers and answers needs to be synced during an active presentation.
This is done using SocketIO together with flask_socketio.
Events sent is also authorized via json web tokens.
Whenever client joins a competition they will connect via sockets.
Only a single instance of a competition can be active at a time.
All of the functionality related to an active competition and sockets can be found in the file `app/core/sockets.py`.
### Starting and joing presentations
Whenever a client types in a code in the client, the code will be checked via the `api/auth/login/code` API call.
If there is such a code and it was an operator code, the client will receive a JWT it will need to use to authenticate itself for there on out.
It will also emit the `start_presentation` event to start the presentation.
If there is such a code and the associated competition is active, the client will also receive a JWT, regardless if it was an operator code or not.
In this case the client will instead emit the `join_presentation` event.
### Syncing between clients
The operator will emit `set_slide` and `set_timer` events that syncs their slides and timers between all clients connected to the same presentation.
The operator can also emit `end_presentation` to end the current presentation, which will disconnect all connected clients.
File suppressed by a .gitattributes entry or the file's encoding is unsupported.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment