Riferimento API

Domain

Contratto astratto dell’entità di dominio Spesa.

class AbstractSpesa[sorgente]

Basi: ABC

Definisce i metodi che ogni entità di tipo Spesa deve implementare.

abstract property data: datetime

Ritorna la data della spesa.

Ritorna:

data della spesa

Tipo di ritorno:

datetime

abstract property descrizione: str

Ritorna la descrizione della spesa.

Ritorna:

descrizione della spesa

Tipo di ritorno:

str

abstract property importo: float

Ritorna l’importo della spesa.

Ritorna:

importo della spesa

Tipo di ritorno:

float

Entità di dominio Spesa.

class Spesa(data, descrizione, importo)[sorgente]

Rappresenta una spesa, implementando il contratto AbstractSpesa.

Le regole di business sono applicate nei setter: una spesa non può avere una data assente, una descrizione troppo corta o un importo non positivo.

Parametri:
  • data (datetime)

  • descrizione (str)

  • importo (float)

property data: datetime

Ritorna la data della spesa.

Ritorna:

data della spesa

Tipo di ritorno:

datetime

property descrizione: str

Ritorna la descrizione della spesa.

Ritorna:

descrizione della spesa

Tipo di ritorno:

str

property importo: float

Ritorna l’importo della spesa.

Ritorna:

importo della spesa

Tipo di ritorno:

float

Contratto astratto del repository delle spese.

class AbstractSpesaRepository[sorgente]

Basi: ABC

Definisce le operazioni che un repository di spese deve offrire.

abstractmethod aggiungi_spesa(spesa)[sorgente]

Aggiunge una nuova spesa al repository.

Parametri:

spesa (AbstractSpesa) – spesa da aggiungere

Tipo di ritorno:

None

abstractmethod ottieni_tutte_le_spese()[sorgente]

Ritorna tutte le spese presenti nel repository.

Ritorna:

tutte le spese presenti nel repository

Tipo di ritorno:

list[AbstractSpesa]

Contratto astratto del servizio di dominio delle spese.

class AbstractSpesaService[sorgente]

Basi: ABC

Contratto del servizio che coordina la logica di dominio sulle spese.

Incapsula la logica di business che può coinvolgere più entità, mediando l’accesso al repository.

abstractmethod aggiungi_spesa(spesa)[sorgente]

Aggiunge una nuova spesa tramite il repository.

Parametri:

spesa (AbstractSpesa) – spesa da aggiungere

Tipo di ritorno:

None

abstractmethod ottieni_tutte_le_spese()[sorgente]

Ritorna tutte le spese tramite il repository.

Ritorna:

tutte le spese disponibili

Tipo di ritorno:

list[AbstractSpesa]

Servizio di dominio delle spese.

class SpesaService(repository)[sorgente]

Implementa AbstractSpesaService delegando al repository.

Dipende dall’astrazione AbstractSpesaRepository (Dependency Inversion): in questo dominio la logica è semplice, ma il servizio fornisce il punto di estensione per regole che coinvolgano più entità.

Parametri:

repository (AbstractSpesaRepository)

aggiungi_spesa(spesa)[sorgente]

Aggiunge una nuova spesa tramite il repository.

Parametri:

spesa (AbstractSpesa) – spesa da aggiungere

Tipo di ritorno:

None

ottieni_tutte_le_spese()[sorgente]

Ritorna tutte le spese tramite il repository.

Ritorna:

tutte le spese disponibili

Tipo di ritorno:

list[AbstractSpesa]

Application

Contratto astratto del DTO di report mensile.

class AbstractReportMensileDto[sorgente]

Basi: ABC

Contratto di un DTO che rappresenta il totale speso in un dato mese.

abstract property data: datetime

Ritorna la data (mese/anno) del report.

Ritorna:

data del report

Tipo di ritorno:

datetime

abstract property importo: float

Ritorna l’importo totale del report.

Ritorna:

importo del report

Tipo di ritorno:

float

DTO di report mensile.

class ReportMensileDto(data, importo)[sorgente]

Totale speso in un mese, implementa AbstractReportMensileDto.

La data viene normalizzata al primo giorno del mese: in questo modo due DTO dello stesso mese sono uguali e raggruppabili.

Parametri:
  • data (datetime)

  • importo (float)

property data: datetime

Ritorna la data (primo giorno del mese) del report.

Ritorna:

data del report

Tipo di ritorno:

datetime

property importo: float

Ritorna l’importo totale del report.

Ritorna:

importo del report

Tipo di ritorno:

float

Contratto astratto generico per i casi d’uso applicativi.

class AbstractUseCase[sorgente]

Basi: ABC, Generic[InputT, OutputT]

Contratto generico di un caso d’uso: trasforma un input in un output.

Il tipo dell’input e dell’output sono parametrici, così ogni caso d’uso dichiara con precisione cosa riceve e cosa restituisce.

abstractmethod execute(dati)[sorgente]

Esegue il caso d’uso.

Parametri:

dati (InputT) – input del caso d’uso (eventualmente None)

Ritorna:

output prodotto dal caso d’uso (eventualmente None)

Tipo di ritorno:

OutputT

Caso d’uso: aggiunta di una nuova spesa.

class AggiungiSpesaUseCase(service)[sorgente]

Aggiunge una nuova spesa delegando al servizio di dominio.

Parametri:

service (AbstractSpesaService)

execute(dati)[sorgente]

Salva la nuova spesa tramite il servizio.

Parametri:

dati (AbstractSpesa) – spesa da aggiungere

Tipo di ritorno:

None

Caso d’uso: generazione del report mensile.

class ReportMensileUseCase(provider)[sorgente]

Restituisce i totali mensili delegando al provider di reporting.

L’aggregazione effettiva (in Python o in SQL) dipende dal motore iniettato tramite AbstractReportingProvider: il caso d’uso resta agnostico.

Parametri:

provider (AbstractReportingProvider)

execute(dati=None)[sorgente]

Ritorna i totali mensili in ordine di data decrescente.

Parametri:

dati (None) – non utilizzato (il caso d’uso non richiede input)

Ritorna:

totali mensili in ordine di data decrescente

Tipo di ritorno:

list[AbstractReportMensileDto]

Caso d’uso: le 10 spese di importo maggiore.

class Top10SpeseUseCase(provider)[sorgente]

Basi: AbstractUseCase[None, list[AbstractSpesa]]

Restituisce le 10 spese maggiori delegando al provider di reporting.

L’ordinamento e la selezione (in Python o in SQL) dipendono dal motore iniettato tramite AbstractReportingProvider.

Parametri:

provider (AbstractReportingProvider)

execute(dati=None)[sorgente]

Ritorna le prime 10 spese per importo decrescente.

Parametri:

dati (None) – non utilizzato (il caso d’uso non richiede input)

Ritorna:

le prime 10 spese per importo decrescente

Tipo di ritorno:

list[AbstractSpesa]

Contratto astratto del provider di reporting (aggregazione in lettura).

class AbstractReportingProvider[sorgente]

Basi: ABC

Porta di reporting: fornisce i report aggregati in sola lettura.

Astrae dove avviene l’aggregazione, così il motore di calcolo (Python in-memory oppure SQL/DuckDB) può essere scambiato senza impatto sui casi d’uso e sui layer superiori (Dependency Inversion).

abstractmethod report_mensile()[sorgente]

Ritorna i totali mensili in ordine di data decrescente.

Ritorna:

totali mensili in ordine di data decrescente

Tipo di ritorno:

list[AbstractReportMensileDto]

abstractmethod top_10()[sorgente]

Ritorna le 10 spese di importo maggiore.

Ritorna:

le prime 10 spese per importo decrescente

Tipo di ritorno:

list[AbstractSpesa]

Provider di reporting in-memory: aggregazione in Python.

class InMemoryReportingProvider(service)[sorgente]

Calcola i report aggregando in memoria con Python.

È il motore di default: recupera tutte le spese tramite il servizio di dominio e ne calcola i report in Python, senza dipendenze esterne.

Parametri:

service (AbstractSpesaService)

report_mensile()[sorgente]

Aggrega le spese per anno/mese sommandone gli importi.

Converte le spese in DTO (data normalizzata al mese), le ordina per data decrescente e le raggruppa per mese sommando gli importi.

Ritorna:

totali mensili in ordine di data decrescente

Tipo di ritorno:

list[AbstractReportMensileDto]

top_10()[sorgente]

Ordina le spese per (importo, data) decrescente e ne prende 10.

Ritorna:

le prime 10 spese per importo decrescente

Tipo di ritorno:

list[AbstractSpesa]

Infrastructure

Contratto astratto della sorgente dati delle spese.

class AbstractSpesaDataSource[sorgente]

Basi: ABC

Definisce le operazioni di una sorgente dati di spese.

L’astrazione consente di sostituire la persistenza (CSV, DB, …) senza impattare i layer superiori.

abstractmethod aggiungi_spesa(spesa)[sorgente]

Aggiunge una nuova spesa alla sorgente dati.

Parametri:

spesa (AbstractSpesa) – spesa da aggiungere

Tipo di ritorno:

None

abstractmethod ottieni_tutte_le_spese()[sorgente]

Ritorna tutte le spese presenti nella sorgente dati.

Ritorna:

tutte le spese presenti nella sorgente dati

Tipo di ritorno:

list[AbstractSpesa]

Sorgente dati delle spese su file CSV.

class SpesaDataSourceCsv(filepath='storico_spese.csv')[sorgente]

Persiste e legge le spese da un file CSV.

Il file ha tre colonne (data, descrizione, importo) e viene creato con l’intestazione alla prima scrittura, se mancante o vuoto.

Parametri:

filepath (str)

property filepath: str

Ritorna il percorso del file CSV usato dalla sorgente.

Utile per far leggere la stessa sorgente a motori alternativi (es. il provider di reporting DuckDB).

Ritorna:

percorso del file CSV

Tipo di ritorno:

str

aggiungi_spesa(spesa)[sorgente]

Aggiunge una nuova spesa alla sorgente dati (creandola se assente).

Parametri:

spesa (AbstractSpesa) – spesa da aggiungere

Tipo di ritorno:

None

ottieni_tutte_le_spese()[sorgente]

Legge tutte le spese dalla sorgente dati.

Ritorna:

tutte le spese presenti nel file (vuoto se la sorgente manca)

Tipo di ritorno:

list[AbstractSpesa]

Implementazione del repository delle spese.

class SpesaRepository(datasource)[sorgente]

Adapter tra il dominio e la sorgente dati.

Implementa il contratto AbstractSpesaRepository delegando a una AbstractSpesaDataSource, da cui dipende solo per astrazione.

Parametri:

datasource (AbstractSpesaDataSource)

aggiungi_spesa(spesa)[sorgente]

Aggiunge una nuova spesa tramite la sorgente dati.

Parametri:

spesa (AbstractSpesa) – spesa da aggiungere

Tipo di ritorno:

None

ottieni_tutte_le_spese()[sorgente]

Ritorna tutte le spese dalla sorgente dati.

Ritorna:

tutte le spese presenti nel repository

Tipo di ritorno:

list[AbstractSpesa]

Provider di reporting basato su DuckDB: aggregazione in SQL.

Richiede l’extra opzionale analytics (pip install gestore-spese[analytics]).

class DuckDbReportingProvider(filepath='storico_spese.csv')[sorgente]

Calcola i report con DuckDB, leggendo il CSV direttamente in SQL.

Dimostra il push-down dell’aggregazione: il calcolo (GROUP BY/SUM, ORDER BY/LIMIT) avviene nel motore dati invece che in Python. Legge la stessa sorgente CSV usata dalla persistenza, senza modificarla.

Parametri:

filepath (str)

report_mensile()[sorgente]

Aggrega i totali mensili in SQL (GROUP BY/SUM).

Ritorna:

totali mensili in ordine di data decrescente

Tipo di ritorno:

list[AbstractReportMensileDto]

top_10()[sorgente]

Seleziona le 10 spese maggiori in SQL (ORDER BY/LIMIT).

Ritorna:

le prime 10 spese per importo decrescente

Tipo di ritorno:

list[AbstractSpesa]

Factory che seleziona il motore di reporting in base alla configurazione.

ENV_VARIABILE_MOTORE = 'GESTORE_SPESE_ENGINE'

Variabile d’ambiente che seleziona il motore di reporting.

MOTORE_DUCKDB = 'duckdb'

Valore per il motore SQL DuckDB.

MOTORE_INMEMORY = 'inmemory'

Valore (e default) per il motore Python in-memory.

crea_reporting_provider(service, csv_filepath, motore=None)[sorgente]

Crea il provider di reporting secondo il motore richiesto.

Se motore non è passato, viene letto dalla variabile d’ambiente GESTORE_SPESE_ENGINE; il default è il motore Python in-memory. Il valore duckdb seleziona il motore SQL: se l’extra analytics non è installato si ricade automaticamente sull’in-memory, con un avviso, così l’applicazione non si interrompe mai.

Parametri:
  • service (AbstractSpesaService) – servizio usato dal motore in-memory

  • csv_filepath (str) – percorso del CSV letto dal motore DuckDB

  • motore (str | None) – motore richiesto (inmemory o duckdb); se None viene letto dall’ambiente

Ritorna:

il provider di reporting selezionato

Tipo di ritorno:

AbstractReportingProvider

Interfaces

Contratto astratto di un comando della CLI (pattern Command).

class AbstractCommand[sorgente]

Basi: ABC

Definisce l’interfaccia di un comando invocabile dalla CLI.

abstractmethod execute()[sorgente]

Esegue l’azione associata al comando.

Tipo di ritorno:

None

Comando CLI: aggiunta di una nuova spesa.

class AggiungiSpesaCommand(use_case)[sorgente]

Raccoglie i dati da terminale e aggiunge una nuova spesa.

Parametri:

use_case (AggiungiSpesaUseCase)

execute()[sorgente]

Esegue il flusso completo: input -> caso d’uso -> output.

Tipo di ritorno:

None

Comando CLI: visualizzazione del report mensile.

class ReportMensileCommand(use_case)[sorgente]

Mostra a video il report mensile delle spese.

Parametri:

use_case (ReportMensileUseCase)

execute()[sorgente]

Esegue il caso d’uso e ne mostra il risultato.

Tipo di ritorno:

None

Comando CLI: visualizzazione delle 10 spese maggiori.

class Top10SpeseCommand(use_case)[sorgente]

Mostra a video le 10 spese di importo maggiore.

Parametri:

use_case (Top10SpeseUseCase)

execute()[sorgente]

Esegue il caso d’uso e ne mostra il risultato.

Tipo di ritorno:

None

CLI del Gestore delle Spese Domestiche: composition root ed entry point.

Espone GestoreSpeseCli (che istanzia e collega tutti i componenti dei layer sottostanti) e la funzione main(), registrata come console script gestore-spese in pyproject.toml.

class VoceMenu(descrizione, comando)[sorgente]

Basi: object

Voce del menu della CLI.

Parametri:
  • descrizione (str) – testo mostrato all’utente

  • comando (AbstractCommand | None) – comando da eseguire, oppure None per la voce di uscita

class GestoreSpeseCli[sorgente]

Basi: object

Interfaccia a riga di comando dell’applicazione.

Funge da composition root: costruisce la catena di dipendenze (datasource -> repository -> service -> casi d’uso -> comandi) e guida l’utente attraverso un menu interattivo.

Il motore di reporting (in-memory di default, oppure DuckDB/SQL) è scelto qui dalla factory in base alla variabile d’ambiente GESTORE_SPESE_ENGINE.

run()[sorgente]

Avvia il loop interattivo del menu fino all’uscita.

Tipo di ritorno:

None

main()[sorgente]

Punto di ingresso del comando console gestore-spese.

Tipo di ritorno:

None