1
Fork 0
mirror of https://github.com/Steffo99/sophon.git synced 2024-12-21 22:34:21 +00:00

My nvidia is on fire

This commit is contained in:
Steffo 2021-11-04 22:34:13 +01:00
parent 1f83a41e3f
commit 00d25deb9f
7 changed files with 342 additions and 145 deletions

View file

@ -0,0 +1,16 @@
Librerie e tecnologie utilizzate
--------------------------------
.. note::
Sono elencate solo le principali librerie utilizzate; dipendenze e librerie minori non sono specificate, ma sono visibili all'interno del file ``poetry.lock``.
- Il linguaggio di programmazione `Python <https://www.python.org/>`_
- Il gestore di dipendenze `Poetry <https://python-poetry.org/>`_
- Il framework web `Django <https://www.djangoproject.com/>`_
- L'estensione per Django `Django REST Framework <https://www.django-rest-framework.org/>`_
- L'estensione per Django `Django CORS Headers <https://github.com/adamchainz/django-cors-headers>`_
- L'adattatore database per PostgreSQL `Psycopg <https://pypi.org/project/psycopg2/>`_
- Il `Docker SDK for Python <https://docker-py.readthedocs.io/en/stable/>`_
- I server web `Gunicorn <https://gunicorn.org/>`_ e `Uvicorn <https://www.uvicorn.org/>`_
- L'utilità `lazy-object-proxy <https://github.com/ionelmc/python-lazy-object-proxy>`_

View file

@ -0,0 +1,89 @@
Il progetto sophon
------------------
.. default-domain:: py
.. default-role:: obj
.. module:: sophon
Il progetto Django Sophon aggiunge varie funzionalità al template base dei progetti Django.
Pagina di amministrazione personalizzata
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. module:: sophon.admin
La pagina di amministrazione viene personalizzata con la classe `SophonAdminSite`, che modifica alcuni parametri della classe base.
Inoltre, il template predefinito viene sovrascritto da quello all'interno del file ``templates/admin/base.html``, che sostituisce il foglio di stile con uno personalizzato per Sophon.
.. class:: SophonAdminSite(django.contrib.admin.AdminSite)
.. attribute:: site_header = "Sophon Server Administration"
Il nome della pagina nell'header viene modificato a *Sophon Server Administration*.
.. attribute:: site_title = "Sophon Server Administration"
Il titolo della pagina nell'header viene anch'esso modificato a *Sophon Server Administration*.
.. attribute:: site_url = None
Il collegamento *View Site* viene rimosso, in quanto è possibile accedere all'interfaccia web di Sophon da più domini contemporaneamente.
.. attribute:: index_title = "Resources Administration"
Il titolo dell'indice viene modificato a *Resources Administration*.
.. class:: SophonAdminConfig(django.contrib.admin.apps.AdminConfig)
.. attribute:: default_site = "sophon.admin.SophonAdminSite"
`.SophonAdminSite` è selezionata come classe predefinita per il sito di amministrazione.
Impostazioni dinamiche
^^^^^^^^^^^^^^^^^^^^^^
.. module:: sophon.settings
Il file di impostazioni viene modificato per **permettere la configurazione attraverso variabili di ambiente** invece che attraverso il file ``settings.py``, rendendo il deployment con Docker molto più semplice.
.. code-block:: python
try:
DATABASE_ENGINE = os.environ["DJANGO_DATABASE_ENGINE"]
except KeyError:
log.warning("DJANGO_DATABASE_ENGINE was not set, defaulting to PostgreSQL")
DATABASE_ENGINE = "django.db.backends.postgresql"
log.debug(f"{DATABASE_ENGINE = }")
Inoltre, viene configurato il modulo `logging` per emettere testo colorato di più facile comprensione usando il package `coloredlogs`.
.. code-block:: python
"detail": {
"()": coloredlogs.ColoredFormatter,
"format": "{asctime:>19} | {name:<24} | {levelname:>8} | {message}",
"style": "{",
}
Autenticazione migliorata
^^^^^^^^^^^^^^^^^^^^^^^^^
.. module:: sophon.auth1
La classe `rest_framework.authentication.TokenAuthentication` viene modificata per ottenere un comportamento conforme agli standard del web.
.. class:: BearerTokenAuthentication(rest_framework.authentication.TokenAuthentication)
.. attribute:: keyword = "Bearer"
Si configura `rest_framework` per accettare header di autenticazione nella forma ``Bearer <token>``, invece che ``Token <token>``.
.. module:: sophon.auth2
La view `rest_framework.authtoken.views.ObtainAuthToken` viene estesa per aggiungere dati alla risposta di autenticazione riuscita.
.. class:: CustomObtainAuthToken(rest_framework.authtoken.views.ObtainAuthToken)
.. method:: post(self, request, *args, **kwargs)
In particolare, viene aggiunta una chiave ``user``, che contiene i dettagli sull'utente che ha effettuato il login.

View file

@ -0,0 +1,214 @@
L'app sophon.core
-----------------
.. default-domain:: py
.. default-role:: obj
.. module:: sophon.core
L'app `sophon.core` è l'app principale del progetto, e non può essere disattivata, in quanto dipendenza obbligatoria di tutte le altre app.
Aggiunta di un nuovo comando di gestione
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. module:: sophon.core.management.commands.initsuperuser
Per permettere l'integrazione la creazione automatica del primo :ref:`superutente` quando Sophon viene eseguito da Docker, viene introdotto il comando di gestione ``initsuperuser``.
.. class:: Command
Questo comando crea automaticamente un :ref:`superutente` con le credenziali specificate in :ref:`\`\`DJANGO_SU_USERNAME\`\``, :ref:`\`\`DJANGO_SU_EMAIL\`\`` e :ref:`\`\`DJANGO_SU_PASSWORD\`\``.
Modello base astratto
^^^^^^^^^^^^^^^^^^^^^
.. module:: sophon.core.models
Viene estesa la classe astratta `django.db.models.Model` con funzioni per stabilire il livello di accesso di un utente all'oggetto e per generare automaticamente i `rest_framework.serializers.ModelSerializer` in base al livello di accesso.
.. class:: SophonModel(django.db.models.Model)
.. method:: can_edit(self, user: django.contrib.auth.models.User) -> bool
:abstractmethod:
Controlla se un utente può modificare l'oggetto attuale.
:param user: L'utente da controllare.
:returns: `True` se l'utente deve poter modificare l'oggetto, altrimenti `False`.
.. method:: can_admin(self, user: django.contrib.auth.models.User) -> bool
:abstractmethod:
Controlla se un utente può amministrare l'oggetto attuale.
:param user: L'utente da controllare.
:returns: `True` se l'utente deve poter amministrare l'oggetto, altrimenti `False`.
.. classmethod:: get_fields(cls) -> set[str]
:returns: il `set` di nomi di campi che devono essere mostrati quando viene richiesto l'oggetto attraverso l'API.
.. classmethod:: get_editable_fields(cls) -> set[str]
:returns: il `set` di nomi di campi di cui deve essere permessa la modifica se l'utente può modificare (`.can_edit`) l'oggetto.
.. classmethod:: get_administrable_fields(cls) -> set[str]
:returns: il `set` di nomi di campi di cui deve essere permessa la modifica se l'utente può amministrare (`.can_admin`) l'oggetto.
.. classmethod:: get_creation_fields(cls) -> set[str]
:returns: il `set` di nomi di campi che possono essere specificati dall'utente al momento della creazione dell'oggetto.
Modello di autorizzazione astratto
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Viene definito un nuovo modello astratto, basato su `SophonModel`, che permette di determinare i permessi dell'utente in base alla sua appartenenza al gruppo a cui è collegato l'oggetto implementatore.
.. class:: SophonGroupModel(SophonModel)
.. method:: get_group(self) -> ResearchGroup
:abstractmethod:
:returns: Il gruppo a cui appartiene l'oggetto.
.. classmethod:: get_access_to_edit(cls) -> sophon.core.enums.SophonGroupAccess
:returns: Il livello di autorità all'interno del gruppo necessario per modificare l'oggetto.
.. classmethod:: get_access_to_admin(cls) -> sophon.core.enums.SophonGroupAccess
:returns: Il livello di autorità all'interno del gruppo necessario per amministrare l'oggetto.
.. method:: get_access_serializer(self, user: User) -> typing.Type[rest_framework.serializers.ModelSerializer]
:returns: Restituisce il `rest_framework.serializers.ModelSerializer` adeguato al livello di autorità dell'utente.
.. class:: sophon.core.enums.SophonGroupAccess(enum.IntEnum)
Enumerazione che stabilisce il livello di autorità che un utente può avere all'interno di un gruppo.
.. attribute:: NONE = 0
Utente :ref:`ospite`.
.. attribute:: REGISTERED = 10
:ref:`Utente` registrato.
.. attribute:: MEMBER = 50
Membro del :ref:`gruppo di ricerca`.
.. attribute:: OWNER = 100
Creatore del :ref:`gruppo di ricerca`.
.. attribute:: SUPERUSER = 200
:ref:`Superutente` con privilegi universali.
Modello dei dettagli dell'istanza
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Viene creato il modello che rappresenta i dettagli dell':ref:`istanza` Sophon.
.. class:: SophonInstanceDetails(SophonModel)
.. attribute:: id: IntegerField [1]
Impostando ``1`` come unica scelta per il campo della chiave primaria ``id``, si crea un modello "singleton", ovvero un modello di cui può esistere un'istanza sola in tutto il database.
.. attribute:: name: CharField
.. attribute:: description: TextField
.. attribute:: theme: CharField ["sophon", "paper", "royalblue", "hacker", "amber"]
.. method:: version: str
:property:
:returns: La versione installata del pacchetto `sophon`.
.. seealso::
:ref:`Sophon instance details` nella guida per l'amministratore.
Modello del gruppo di ricerca
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. class:: ResearchGroup(SophonGroupModel)
Modello che rappresenta un :ref:`gruppo di ricerca`.
.. attribute:: slug: SlugField
.. attribute:: name: CharField
.. attribute:: description: TextField
.. attribute:: members: ManyToManyField → django.contrib.auth.models.User
.. attribute:: owner: ForeignKey → django.contrib.auth.models.User
.. attribute:: access: CharField ["MANUAL", "OPEN"]
Estensione ai permessi di Django
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. module:: sophon.core.permissions
I permessi di `rest_framework` vengono estesi con due nuove classi che utilizzano il :ref:`modello di autorizzazione` precedentemente definito.
.. class:: Edit(rest_framework.permissions.BasePermission)
Consente l'interazione solo agli utenti che possono modificare (`.can_edit`) l'oggetto.
.. class:: Admin(rest_framework.permissions.BasePermission)
Consente l'interazione solo agli utenti che possono amministrare (`.can_admin`) l'oggetto.
Viewset astratte
^^^^^^^^^^^^^^^^
.. module:: sophon.core.views
Vengono definiti due viewset in grado di utilizzare i metodi aggiunti dalle classi astratte `.models.SophonModel` e `.models.SophonGroupModel`.
.. class:: ReadSophonViewSet(rest_framework.viewsets.ReadOnlyModelViewSet, metaclass=abc.ABCMeta)
Estende la classe base `rest_framework.viewsets.ReadOnlyModelViewSet` con metodi di utilità mancanti nell'implementazione originale, allacciandola inoltre a `.models.SophonGroupModel`.
.. method:: get_queryset(self) -> QuerySet
:abstractmethod:
Imposta come astratto (e quindi obbligatorio) il metodo `rest_framework.viewsets.ReadOnlyModelViewSet.get_queryset`.
.. method:: permission_classes(self)
:property:
Sovrascrive il campo di classe `rest_framework.viewsets.ReadOnlyModelViewSet.permission_classes` con una funzione, permettendone la selezione dei permessi richiesti al momento di ricezione di una richiesta HTTP (invece che al momento di definizione della classe).
Delega la selezione delle classi a `.get_permission_classes`.
.. method:: get_permission_classes(self) -> typing.Collection[typing.Type[permissions.BasePermission]]
Funzione che permette la selezione dei permessi necessari per effetuare una determinata richiesta al momento di ricezione di quest'ultima.
Utile per le classi che erediteranno da questa.
.. method:: get_serializer_class(self) -> typing.Type[Serializer]
:final:
Funzione che permette la selezione del `rest_framework.serializers.Serializer` da utilizzare per una determinata richiesta al momento di ricezione di quest'ultima.
Utilizza:
- il serializzatore **in sola lettura** per elencare gli oggetti (azione ``list``);
- il serializzatore **di creazione** per creare nuovi oggetti (azione ``create``) e per generare i metadati del viewset (azione ``metadata``);
- il serializzatore ottenuto da `.models.SophonGroupModel.get_access_serializer` per la visualizzazione dettagliata (azione ``retrieve``), la modifica (azioni ``update`` e ``partial_update``) e l'eliminazione (azione ``destroy``) di un singolo oggetto;
- il serializzatore ottenuto da `.get_custom_serializer_classes` per le azioni personalizzate.
.. seealso::
`.models.SophonGroupModel`
.. method:: get_custom_serializer_classes(self) -> t.Type[Serializer]
Permette alle classi che ereditano da questa di selezionare quale `rest_framework.serializers.Serializer` utilizzare per le azioni personalizzate.

View file

@ -0,0 +1,6 @@
L'app sophon.projects
-----------------------
.. default-domain:: py
.. default-role:: obj
.. module:: sophon.projects

View file

@ -0,0 +1,6 @@
L'app sophon.notebooks
----------------------
.. default-domain:: py
.. default-role:: obj
.. module:: sophon.notebooks

View file

@ -4,153 +4,17 @@ Modulo backend
.. default-role:: obj
.. py:currentmodule:: sophon
Il *modulo backend* consiste in un server web che consente agli utenti:
- Attraverso l'API:
- *autenticazione* e *autorizzazione* degli utenti;
- *visualizzazione*, *interazione*, *creazione*, *modifica* ed *eliminazione* di gruppi di ricerca, progetti di ricerca e notebook
- *visualizzazione* di utenti e dettagli sull'istanza Sophon.
- Attraverso pagine web dinamiche:
- *amministrazione* dell'istanza Sophon.
Inoltre, effettua le seguenti operazioni in risposta a determinate richieste effettuate dagli utenti:
- *configurazione*, *avvio* e *arresto* di container Docker basati sulle immagini specificate dai notebook;
- *configurazione*, *attivazione* e *disattivazione* del servizio di proxying effettuato dal :ref:`modulo proxy`.
Il *modulo backend* consiste in un server web che espone un'API e un sito web per l'amministrazione.
È collocato all'interno del repository in ``/backend``.
È formato dal package Python `sophon`, che contiene al suo interno un progetto Django, che a sua volta contiene le tre app Django `sophon.core`, `sophon.projects` e `sophon.notebooks`.
Librerie e tecnologie utilizzate
--------------------------------
.. note::
Sono elencate solo le principali librerie utilizzate; dipendenze e librerie minori non sono specificate, ma sono visibili all'interno del file ``poetry.lock``.
- Il linguaggio di programmazione `Python <https://www.python.org/>`_
- Il gestore di dipendenze `Poetry <https://python-poetry.org/>`_
- Il framework web `Django <https://www.djangoproject.com/>`_
- L'estensione per Django `Django REST Framework <https://www.django-rest-framework.org/>`_
- L'estensione per Django `Django CORS Headers <https://github.com/adamchainz/django-cors-headers>`_
- L'adattatore database per PostgreSQL `Psycopg <https://pypi.org/project/psycopg2/>`_
- Il `Docker SDK for Python <https://docker-py.readthedocs.io/en/stable/>`_
- I server web `Gunicorn <https://gunicorn.org/>`_ e `Uvicorn <https://www.uvicorn.org/>`_
- L'utilità `lazy-object-proxy <https://github.com/ionelmc/python-lazy-object-proxy>`_
Struttura del modulo
--------------------
Il modulo consiste nel package Python :mod:`sophon`, che contiene al suo interno un progetto Django, che a sua volta contiene tre app Django.
Il progetto `sophon`
^^^^^^^^^^^^^^^^^^^^
.. module:: sophon
Il progetto Django Sophon aggiunge varie funzionalità al template base dei progetti Django.
Pagina di amministrazione personalizzata
""""""""""""""""""""""""""""""""""""""""
.. module:: sophon.admin
.. class:: SophonAdminSite(django.contrib.admin.AdminSite)
La pagina di amministrazione viene personalizzata con la classe `SophonAdminSite`, che sovrascrive alcuni parametri della classe di default.
Inoltre, il template predefinito viene sovrascritto da quello all'interno del file ``templates/admin/base.html``, che sostituisce il foglio di stile con uno personalizzato per Sophon.
.. attribute:: site_header = "Sophon Server Administration"
Il nome della pagina nell'header viene modificato a *Sophon Server Administration*.
.. attribute:: site_title = "Sophon Server Administration"
Il titolo della pagina nell'header viene anch'esso modificato a *Sophon Server Administration*.
.. attribute:: site_url = None
Il collegamento *View Site* viene rimosso, in quanto è possibile accedere all'interfaccia web di Sophon da più domini contemporaneamente.
.. attribute:: index_title = "Resources Administration"
Il titolo dell'indice viene modificato a *Resources Administration*.
.. class:: SophonAdminConfig(django.contrib.admin.apps.AdminConfig)
La configurazione di default della pagina di amministrazione viene sovrascritta da questa classe.
.. attribute:: default_site = "sophon.admin.SophonAdminSite"
`.SophonAdminSite` è selezionata come classe predefinita.
Impostazioni dinamiche
""""""""""""""""""""""
.. module:: sophon.settings
Il file di impostazioni viene modificato per **permettere la configurazione attraverso variabili di ambiente** invece che attraverso il file ``settings.py``, rendendo il deployment con Docker molto più semplice.
.. code-block:: python
try:
DATABASE_ENGINE = os.environ["DJANGO_DATABASE_ENGINE"]
except KeyError:
log.warning("DJANGO_DATABASE_ENGINE was not set, defaulting to PostgreSQL")
DATABASE_ENGINE = "django.db.backends.postgresql"
log.debug(f"{DATABASE_ENGINE = }")
Inoltre, viene configurato il modulo `logging` per emettere testo colorato di più facile comprensione usando il package `coloredlogs`.
.. code-block:: python
"detail": {
"()": coloredlogs.ColoredFormatter,
"format": "{asctime:>19} | {name:<24} | {levelname:>8} | {message}",
"style": "{",
}
Autenticazione migliorata
"""""""""""""""""""""""""
.. module:: sophon.auth1
.. class:: BearerTokenAuthentication(rest_framework.authentication.TokenAuthentication)
La classe `rest_framework.authentication.TokenAuthentication` viene modificata per ottenere un comportamento conforme agli standard del web.
.. attribute:: keyword = "Bearer"
Si configura `rest_framework` per accettare header di autenticazione nella forma ``Bearer <token>``, invece che ``Token <token>``.
.. module:: sophon.auth2
.. class:: CustomObtainAuthToken(rest_framework.authtoken.views.ObtainAuthToken)
La view `rest_framework.authtoken.views.ObtainAuthToken` viene estesa per aggiungere dati alla risposta di autenticazione riuscita.
.. method:: post(self, request, *args, **kwargs)
In particolare, viene aggiunta una chiave ``user``, che contiene i dettagli sull'utente che ha effettuato il login.
.. todo: whoa ma io mi ero scordato di sta cosa
L'app `sophon.core`
^^^^^^^^^^^^^^^^^^^
.. module:: sophon.core
L'app `sophon.projects`
^^^^^^^^^^^^^^^^^^^^^^^
.. module:: sophon.projects
L'app `sophon.notebooks`
^^^^^^^^^^^^^^^^^^^^^^^^
.. module:: sophon.notebooks
.. toctree::
:maxdepth: 1
1_techstack
2_sophon
3_core
4_projects
5_notebooks

View file

@ -3,6 +3,8 @@ Struttura del progetto
Sophon è composto da quattro moduli, *backend*, *frontend*, *proxy* e *jupyter*, che interagiscono tra loro per fornire agli utenti tutti i servizi necessari.
.. toctree::
:maxdepth: 2