Classeviva.py
contiene al suo interno i seguenti moduli:
classeviva
: modulo principale, contiene tutti i metodi per la gestione della APIclasseviva.collegamenti
: URL dell'APIclasseviva.eccezioni
: eccezioni che possono essere sollevate da Classeviva.pyclasseviva.variabili
: costanti e classi per gestire i dati di Classeviva
Classeviva è il modulo che contiene le classi per la comunicazione con il sito di Classeviva
Segue l'elenco delle classi pubbliche del modulo classeviva:
- Utente: classe che rappresenta un utente
- ListaUtenti: classe che rappresenta una lista di utenti
Rappresenta un utente di Classeviva, di tipo Studente [1]
Classe
class Utente(object)
Costruttore
def __init__( self, id: str, password: str ) -> None:Parametri:
id
: username dell'utentepassword
: password dell'utente
Attributi
self.id: str
: username dell'utentepassword: str
: password dell'utente_sessione: requests.Session
: sessione di comunicazione con l'API_dati: dict
: dati dell'utente
Proprietà
Semplici
biglietto_completo: dict[str, str]
- Biglietto [2]biglietto: str
- il biglietto, in forma di stringa e non in formato JSON [JSON]secondi_rimasti: int
- secondi rimasti alla sessione [3]stato: bool
- comunica se la sessione è ancora attivaconnesso: bool
- comunica se la sessione è attiva senza fare richieste all'APItoken: str
- token della sessionepagelle: list[dict[str, str]]
- pagelle in formato JSON [4]Complesse
dati: dict[str, str]
- dati dell'utentereturn { "id": self._dati["ident"], "nome": self._dati["firstName"], "cognome": self._dati["lastName"] }
Metodi
await self.accedi()
- effettua l'accesso alla sessione [6]async def accedi(self) -> None:Eccezioni
classeviva.eccezioni.PasswordNonValida
- eccezione generata in caso di errore 422, dato da una password che non combacia con l'usernameclasseviva.eccezioni.ErroreHTTP
- eccezione generata in caso di errore con altro codice HTTP
await self.documenti()
- restituisce i documenti dell'utente [5]async def documenti(self) -> dict[str, list[dict[str, str]]]:Ritorno
dict[str, list[dict[str, str]]]
- i documenti dell'utente in formato JSON [5]Eccezioni
classeviva.eccezioni.ErroreHTTP
- eccezione generata in caso di errore HTTP
await self.controlla_documento(documento: str)
- controlla se il documento è presenteasync def controlla_documento(self, documento: str) -> bool:Parametri
documento
: il codice hash del documento da controllareRitorno
bool
- True se il documento è presente, False altrimentiEccezioni
classeviva.eccezioni.ErroreHTTP
- eccezione generata in caso di errore HTTP
await self.assenze()
- ottieni gli eventi in cui l'utente ha fatto assenza [7]async def assenze(self) -> list[dict[str, Any]]:Ritorno
list[dict[str, Any]]
- gli eventi in cui l'utente ha fatto assenza in formato JSON [7]Eccezioni
classeviva.eccezioni.ErroreHTTP
- eccezione generata in caso di errore HTTP
await self.assenze_da(inizio: str=None)
- ottieni gli eventi in cui l'utente ha fatto assenza a partire da una certa dataasync def assenze_da(self, evento: str) -> list[dict[str, Any]]:Parametri
inizio: str
: data di inizio dell'evento da cui partire, in formatoYYYY-MM-DD
Ritorno
list[dict[str, Any]]
- gli eventi in cui l'utente ha fatto assenza in formato JSONEccezioni
classeviva.eccezioni.FormatoNonValido
- il formato della data non è validoclasseviva.eccezioni.DataFuoriGamma
- la data non appartiene all'anno scolastico correnteclasseviva.eccezioni.ErroreHTTP
- eccezione generata in caso di errore HTTP
await self.assenze_da_a(inizio: str=None, fine: str=None)
- ottieni gli eventi compresi tra due date in cui l'utente ha fatto assenzaasync def assenze_da_a(self, inizio: str=None, fine: str=None) -> list[dict[str, Any]]:Parametri
inizio: str
: data di inizio degli eventi da cui partire, in formatoYYYY-MM-DD
fine: str
: data di fine degli eventi fino a cui partire, in formatoYYYY-MM-DD
Ritorno
list[dict[str, Any]]
- gli eventi in cui l'utente ha fatto assenzaEccezioni
classeviva.eccezioni.FormatoNonValido
- il formato della data non è validoclasseviva.eccezioni.DataFuoriGamma
- la data non appartiene all'anno scolastico corrente, oppure la data di fine è precedente alla data di inizioclasseviva.eccezioni.ErroreHTTP
- eccezione generata in caso di errore HTTP
await self.agenda_da_a(inizio: str, fine: str)
- ottieni gli eventi che compongono l'agenda dell'utenteasync def agenda_da_a(self, inizio: str=None, fine: str=None) -> list[dict[str, Any]]:Parametri
inizio: str
: data di inizio degli eventi da cui partire, in formatoYYYY-MM-DD
fine: str
: data di fine degli eventi fino a cui restituirli, in formatoYYYY-MM-DD
Ritorno
list[dict[str, Any]]
- gli eventi dell'argenda nel periodo di tempo specificatoEccezioni
classeviva.eccezioni.FormatoNonValido
- il formato della data non è validoclasseviva.eccezioni.DataFuoriGamma
- la data non appartiene all'anno scolastico corrente, oppure la data di fine è precedente alla data di inizioclasseviva.eccezioni.ErroreHTTP404
- eccezione generata in caso di errore HTTP 404classeviva.eccezioni.ErroreHTTP
- eccezione generata in caso di errore HTTP di altro tipo
await self.agenda_codice_da_a(codice: str, inizio: str, fine: str)
- ottieni gli eventi dell'utente con un determinato codice eventoasync def agenda_codice_da_a(self, codice: str, inizio: str=None, fine: str=None) -> list[dict[str, Any]]:Parametri
codice: str
: codice evento sulla base del quale filtrare gli eventiinizio: str
: data di inizio degli eventi da cui partire, in formatoYYYY-MM-DD
fine: str
: data di fine degli eventi fino a cui restituirli, in formatoYYYY-MM-DD
Ritorno
list[dict[str, Any]]
- gli eventi dell'argenda nel periodo di tempo specificato che hanno il codice evento specificatoEccezioni
classeviva.eccezioni.FormatoNonValido
- il formato della data non è validoclasseviva.eccezioni.DataFuoriGamma
- la data non appartiene all'anno scolastico corrente, oppure la data di fine è precedente alla data di inizioclasseviva.eccezioni.ErroreHTTP404
- eccezione generata in caso di errore HTTP 404classeviva.eccezioni.ErroreHTTP
- eccezione generata in caso di errore HTTP di altro tipo
await self.agenda()
- ottieni gli eventi dell'utente nell'anno scolastico correnteasync def agenda(self) -> list[dict[str, Any]]:Ritorno
list[dict[str, Any]]
- gli eventi dell'agenda nell'anno scolastico correnteEccezioni
classeviva.eccezioni.FormatoNonValido
- il formato della data non è validoclasseviva.eccezioni.DataFuoriGamma
- la data non appartiene all'anno scolastico corrente, oppure la data di fine è precedente alla data di inizioclasseviva.eccezioni.ErroreHTTP404
- eccezione generata in caso di errore HTTP 404classeviva.eccezioni.ErroreHTTP
- eccezione generata in caso di errore HTTP di altro tipo
await self.didattica()
- ottieni il materiale in didattica dell'anno scolastico correnteasync def didattica(self) -> list[dict[str, Any]]:Ritorno
list[dict[str, Any]]
- il materiale in didattica dell'anno scolastico corrente [19]Eccezioni
classeviva.eccezioni.ErroreHTTP
- eccezione sollevata in caso di errore HTTP
await self.didattica_elemento(contenuto: int)
- ottieni un contenuto dal materiale in didatticaasync def didattica_elemento(self, contenuto: int) -> Any:Parametri
contenuto: int
: codice del contenuto da ottenereRitorno
Any
- il contenuto richiestoAvvertenze
- L'endpoint restituisce lo stesso contenuto di
didattica()
Eccezioni
classeviva.eccezioni.ErroreHTTP
- eccezione sollevata in caso di errore HTTP
await self.bacheca()
- ottieni il materiale in bachecaasync def bacheca(self) -> list[dict[str, str | bool | dict[str, str | int]]]:Ritorno
list[dict[str, str | bool | dict[str, str | int]]]
- il materiale in bachecaEccezioni
classeviva.eccezioni.ErroreHTTP
- eccezione sollevata in caso di errore HTTP
await self.bacheca_leggi(contenuto: int)
- ottieni un contenuto dal materiale in bachecaasync def bacheca_leggi(self, codice: int, id_: int) -> dict[str, dict[str, Any]]:Parametri
codice: int
: codice dell'evento (alla voceevtCode
)id_: int
: id del contenuto da ottenere (alla vocepubId
)Ritorno
dict[str, dict[str, Any]]
- il contenuto richiestoEccezioni
classeviva.eccezioni.ErroreHTTP
- eccezione sollevata in caso di errore HTTP
await self.bacheca_allega(codice: int, id_: int)
- ottieni un allegatoasync def bacheca_allega(self, codice: int, id_: int) -> bytes:Parametri
codice: int
: codice dell'evento (alla voceevtCode
)id_: int
: id del contenuto da ottenere (alla vocepubId
)Ritorno
bytes
- il contenuto richiesto in formato binarioEccezioni
classeviva.eccezioni.ErroreHTTP
- eccezione sollevata in caso di errore HTTPAlias
bacheca_allegato
- alias perbacheca_allega
await self.lezioni()
- ottieni tutte le lezioni dell'annoasync def lezioni(self) -> list[dict[str, Any]]:Avvertenze
- L'endpoint restituisce
{"lessons": []}
in ogni caso
await self.lezioni_giorno(giorno: str)
- ottieni le lezioni del giornoasync def lezioni_giorno(self, giorno: str=None) -> Any:Parametri
giorno: str
: giorno di cui si richiede la lezione, in formatoYYYY-MM-DD
Ritorno
list[dict[str, Any]]
- le lezioni del giorno richiesto [20]Eccezioni
classeviva.eccezioni.FormatoNonValido
- il formato della data non è validoclasseviva.eccezioni.DataFuoriGamma
- la data non appartiene all'anno scolastico corrente, oppure la data di fine è precedente alla data di inizioclasseviva.eccezioni.ErroreHTTP
- eccezione sollevata in caso di errore HTTP
await self.lezioni_da_a(inizio: str, fine: str)
- ottieni le lezioni in un range di dateasync def lezioni_da_a(self, inizio: str, fine: str) -> list[dict[str, Any]]:Parametri
inizio: str
: data di inizio, in formatoYYYY-MM-DD
fine: str
: data di fine, in formatoYYYY-MM-DD
Ritorno
list[dict[str, Any]]
- le lezioni del range richiesto [20]Eccezioni
classeviva.eccezioni.FormatoNonValido
- il formato della data non è validoclasseviva.eccezioni.DataFuoriGamma
- la data non appartiene all'anno scolastico corrente, oppure la data di fine è precedente alla data di inizioclasseviva.eccezioni.ErroreHTTP
- eccezione sollevata in caso di errore HTTP
await self.calendario()
- ottieni il calendario [21]async def calendario(self) -> list[dict[str, str | int]]:Ritorno
list[dict[str, str | int]]
- il calendario [21]Eccezioni
classeviva.eccezioni.ErroreHTTP
- eccezione sollevata in caso di errore HTTP
await self.libri()
- ottieni i libri di testo adottati per l'anno scolastico corrente [22]async def libri(self) -> dict[str, int | str | dict[str, Any]]:Ritorno
dict[str, int | str | dict[str, Any]]
- i libri di testo adottati per l'anno scolastico corrente [22]Eccezioni
classeviva.eccezioni.ErroreHTTP
- eccezione sollevata in caso di errore HTTP
await self.carta()
- ottieni la carta dello studente [23]async def carta(self) -> dict[str, str | int]:Ritorno
dict[str, str | int]
- la carta dello studente [23]Eccezioni
classeviva.eccezioni.ErroreHTTP
- eccezione sollevata in caso di errore HTTP
await self.voti()
- ottieni le valutazioni dello studente [24]async def voti(self) -> list[dict[str, str | int | NoneType]]:Ritorno
list[dict[str, str | int | NoneType]]
- le valutazioni dello studente [24]Eccezioni
classeviva.eccezioni.ErroreHTTP
- eccezione sollevata in caso di errore HTTP
await self.periodi()
- ottieni la suddivisione in periodi dell'anno [25]async def periodi(self) -> list[dict[str, str | int | bool | NoneType]]:Ritorno
list[dict[str, str | int | bool | NoneType]]
- la suddivisione in periodi dell'anno [25]Eccezioni
classeviva.eccezioni.ErroreHTTP
- eccezione sollevata in caso di errore HTTP
await self.materie()
- ottieni le materie e gli insegnanti [26]async def materie(self) -> list[dict[str, str | int | list[dict[str, str]]]]:Ritorno
list[dict[str, str | int | list[dict[str, str]]]]
- le materie e gli insegnanti [26]Eccezioni
classeviva.eccezioni.ErroreHTTP
- eccezione sollevata in caso di errore HTTP
Metodi magici [11]
self.__call__()
|self()
- connette in modo sincrono l'utentedef __call__(self) -> None: asyncio.run(self.accedi())
self.__eq__()
- gestisce le uguaglianzedef __eq__(self, other) -> bool: if (isinstance(other, Utente)): return (self.id == other.id and self.password == other.password) return False
Decoratori
@classeviva.Utente.connettente
- passa l'utente alla funzione come primo parametro dopo aver chiamato il metodoaccedi()
@utente_.connettente def foo(x: classeviva.Utente) -> None: print(x.dati)Avvertenze
- Non funziona con le funzioni asincrone (
async def
) [8]
Un'espansione di un set
di classeviva.Utente
, con metodi utili a eliminare duplicati e ad eseguire in modo asincrono i metodi iterando sugli utenti.
Classe
class ListaUtenti(set[Utente])
Costruttore
def __init__( self, utenti: Iterable[Utente] ) -> None:Parametri:
utenti: Iterable[Utente]
- iterabile contenente [9] oggetti di tipoclasseviva.Utente
Proprietà
connessi: set[Utente]
- elenco degli alunni connessi [10] della lista@property def connessi(self) -> set[Utente]: return {utente for utente in self if (utente.connesso)}
non_connessi: set[Utente]
- elenco degli alunni non connessi [10] della lista@property def non_connessi(self) -> set[Utente]: return {utente for utente in self if (not utente.connesso)}
Metodi
await self.accedi()
- effettua l'accesso alla sessione [6] per tutti gli utentiasync def accedi(self) -> None: await asyncio.gather(*[utente.accedi() for utente in self.non_connessi])
self.aggiungi(utente)
- aggiunge un utente alla listadef aggiungi(self, utente: Utente) -> bool: if (isinstance(utente, Utente) and utente not in self): self.add(utente) return True return FalseParametri
utente: Utente
: l'utente da aggiungereRitorno
bool
- True se l'utente è stato aggiunto, False altrimentiAvvertenze
- Utilizza il metodo
add()
della classeset
da cui eredita, potrebbe sollevare delle eccezioni non gestite dal programma
Metodi magici [11]
self.__call__()
|self()
- connette in modo sincrono tutti gli utentidef __call__(self) -> None: asyncio.run(self.accedi())
self.__add__()
- gestisce le addizioni (+
,+=
)def __add__(self, oggetto) -> ListaUtenti: if (isinstance(oggetto, Utente)): self.aggiungi(oggetto) elif (isinstance(oggetto, IterableABC)): for oggetto_ in oggetto: self.aggiungi(oggetto_) else: raise TypeError(f"{oggetto} non è un oggetto valido")
self.__contains__()
- stabilisce se un utente è presente nella listadef __contains__(self, utente: Utente) -> bool: if (isinstance(utente, Utente)): for utentino in self: if (utente == utentino): return True return False
Decoratori
@classeviva.ListaUtenti.iterante
- ripete le operazioni della funzione decorata su tutti i membri della lista quando viene chiamata@lista_utenti.iterante def foo(x: classeviva.ListaUtenti) -> None: print(x.connessi)
classeviva.collegamenti
[13]
classeviva.collegamenti
è il modulo che contiene gli URL per le richieste all'API di ClasseViva. [14]
La classe classeviva.collegamenti.Collegamenti
contiene gli URL per le richieste all'API di ClasseViva [15]
L'intero codice del modulo è riportato qui, perché breve ed esemplificativo di sé stesso.
class Collegamenti:
base: str = "https://web.spaggiari.eu/rest"
accesso: str = f"{base}/v1/auth/login"
stato: str = f"{base}/v1/auth/status"
biglietto: str = f"{base}/v1/auth/ticket"
documenti: str = f"{base}/v1/students/{{}}/documents"
controllo_documento: str = f"{base}/v1/students/{{}}/documents/check/{{}}"
leggi_documento: str = f"{base}/v1/students/{{}}/documents/read/{{}}"
assenze: str = f"{base}/v1/students/{{}}/absences/details"
classeviva.eccezioni
è il modulo che contiene le eccezioni sollevate da funzioni e metodi contenuti in classeviva
Rappresenta tutti gli errori legati al token di accesso all'API
class TokenErrore(Exception): ...
Sottoclassi
classeviva.eccezioni.TokenNonValido
- il token non è riconosciuto come valido dall'APIclass TokenNonValido(TokenErrore): ...
classeviva.eccezioni.TokenScaduto
- il token è scadutoclass TokenScaduto(TokenErrore): ...
classeviva.eccezioni.TokenNonPresente
- il token non è presente, ovvero non è stato effettuato l'accessoclass TokenNonPresente(TokenErrore): ...
Rappresenta tutti gli errori legati all'utente e in particolare alla compilazione dei suoi campi obbligatori
class UtenteErrore(Exception): """ Errori legati alle utenze """
Sottoclassi
classeviva.eccezioni.PasswordNonValida
- la password non combacia, l'API non ha potuto accettarla [16]class PasswordNonValida(UtenteErrore): ...
Rappresenta tutti gli errori probabilmente dovuti ad un mancato accesso, e che non rientrano in un'altra categoria [17]
class NonAccesso(Exception):
"""
Errori dovuti a un mancato accesso
"""
Sottoclassi
classeviva.eccezioni.SenzaDati
- l'utente non ha tra i suoi attributi privati quelli dati dall'accessoclass SenzaDati(NonAccesso): ...
Rappresenta tutti gli errori HTTP provenienti dalle richieste fatte col modulo requests
class ErroreHTTP(Exception):
...
Fornisce tutte le informazioni date dalla risposta di requests
[18]
raise e.ErroreHTTP(f"""
Richiesta non corretta, codice {response.status_code}
{response.text}
{response.json()}
""")
Sottoclassi
classeviva.eccezioni.ErroreHTTP404
- la richiesta ha restituito un errore 404class ErroreHTTP404(ErroreHTTP): ...
classeviva.variabili
è il modulo che contiene le costanti utili per evitare ridondanza nel codice
L'intero codice del modulo è riportato qui, perché breve ed esemplificativo di sé stesso.
# Constante che indica il tempo di connessione per una sessione
TEMPO_CONNESSIONE: int = 1800
# Constante che indica l'intestazione per le richieste
intestazione: dict[str, str] = {
"content-type": "application/json",
"Z-Dev-ApiKey": "+zorro+",
"User-Agent": "zorro/1.0"
}
[JSON] | Per "formato JSON " si intende il formato restituito dall'API , che non corrisponde con il valore di ritorno della funzione che, utilizzando il modulo json , converte i dati in oggetti di Python |
[1] | Studente, in Classeviva, è un utente il cui identificatore inizia con il carattere 'S' |
[2] | Biglietto, in Classeviva, è una stringa di caratteri, ma non si è ancora capito a cosa serva |
[3] | Richiesta di stato |
[4] | Sezione "schoolReport" della risposta alla richiesta di documenti |
[5] | (1, 2) Sezione "documents" della risposta alla richiesta di documenti |
[6] | (1, 2) Richiesta di accesso |
[7] | (1, 2) Richiesta di assenze |
[8] | Alla versione 0.1.0 , ma è un miglioramento che verrà aggiunto in futuro |
[9] | Non è necessario che contenga soltanto oggetti di quel tipo, grazie al metodo privato __riduci |
[10] | (1, 2) Vengono verificati tramite la loro proprietà Utente.connesso |
[11] | (1, 2) Sono riportati i metodi magici la cui sovrascrittura è rilevante ai fini dell'utilizzo del modulo, gli altri possno essere trovati nel codice sorgente |
[12] | Il metodo __call__ è un metodo magico, che viene chiamato quando si fa utente() |
[13] | Il modulo, alla versione 0.1.0 , è comprensivo di un solo namespace contenente URL |
[14] | Il suo utilizzo è volto alla fase di sviluppo, ma può essere adoperato anche in fase di produzione in caso di necessità |
[15] | Per ogni versione sono disponibili soltanto gli URL per le richieste le cui rispettive funzioni sono già implementate |
[16] | L'API lo comunica tramite una risposta HTTP con codice 422 |
[17] | Ne è un esempio TokenNonPresente , che pur rientrando nella descrizione di NonAccesso non ne è sottoclasse perché già parte di TokenErrore |
[18] | Alla versione 0.1.0 va fatto manualmente sollevando l'eccezione come descritto sotto |
[19] | La struttura dei dizionari contenuti nella lista è complessa, può essere trovata qui |
[20] | (1, 2) Si veda la documentazione |
[21] | (1, 2) Si veda la documentazione |
[22] | (1, 2) Si veda la documentazione |
[23] | (1, 2) Si veda la documentazione |
[24] | (1, 2) Si veda la documentazione |
[25] | (1, 2) Si veda la documentazione |
[26] | (1, 2) Si veda la documentazione |