Salta ai contenuti

Progetti Python

Il generatore di progetti Python può essere utilizzato per creare una libreria o applicazione Python moderna configurata con le best practice, gestita con UV, un singolo lockfile e ambiente virtuale in un workspace UV, pytest per l’esecuzione dei test, Ruff per l’analisi statica e ty per il controllo dei tipi.

Puoi generare un nuovo progetto Python in due modi:

Esegui questo generatore@aws/nx-plugin:py#project

pnpm nx g @aws/nx-plugin:py#project
Componi il tuo comando6

Obbligatorio

Obbligatorio

Opzioni del generatore6 opzioni
nameObbligatoriostring

Il nome del progetto Python

typeObbligatorioenumPredefinito: application

Se il progetto è un'applicazione o una libreria

applicationlibrary
directorystringPredefinito: packages

Directory principale dove viene posizionato il progetto.

subDirectorystring

La sottodirectory in cui viene posizionato il progetto. Per impostazione predefinita corrisponde al nome del progetto.

moduleNamestring

Nome del modulo Python

preferInstallDependenciesbooleanPredefinito: true

Se preferire l'installazione delle dipendenze dopo l'esecuzione del generatore. Impostare su false per rimandare l'installazione quando si eseguono più generatori in batch (l'installazione viene comunque eseguita se necessaria affinché i generatori successivi possano calcolare il grafo dei progetti Nx); installare una volta alla fine.

Il generatore creerà la seguente struttura di progetto nella directory <directory>/<name>:

  • Directory<module-name>
    • __init__.py Module initialisation
  • Directorytests
    • __init__.py Module initialisation
    • conftest.py Test configuration
    • test_noop.py Placeholder test
  • project.json Project configuration and build targets
  • pyproject.toml Packaging configuration file used by UV
  • .python-version Contains the project’s Python version

Potresti anche notare i seguenti file creati/aggiornati nella radice del tuo workspace:

  • pyproject.toml Workspace level packaging configuration for UV
  • .python-version Contains the workspace Python version
  • uv.lock Lockfile for Python dependencies

Aggiungi il tuo codice sorgente Python nella directory <module-name>.

Importare il Codice della tua Libreria in Altri Progetti

Sezione intitolata “Importare il Codice della tua Libreria in Altri Progetti”

Usa il target add per aggiungere una dipendenza a un progetto Python.

Supponiamo di aver creato due progetti python, my_app e my_lib. Questi avranno nomi di progetto completamente qualificati my_scope.my_app e my_scope.my_lib, e per impostazione predefinita avranno ciascuno nomi di modulo my_scope_my_app e my_scope_my_lib.

Affinché my_app dipenda da my_lib, possiamo eseguire il seguente comando:

Terminal window
pnpm nx run my_scope.my_app:add my_scope.my_lib

Puoi quindi importare il codice della tua libreria:

packages/my_app/my_scope_my_app/main.py
from my_scope_my_lib.my_module import my_function

Sopra, my_scope_my_lib è il nome del modulo per la libreria, my_module corrisponde a un file sorgente Python my_module.py, e my_function è un metodo definito in quel file.

Per aggiungere dipendenze al tuo progetto, puoi eseguire il target add nel tuo progetto Python, per esempio:

Terminal window
pnpm nx run my_scope.my_library:add some-pip-package

Questo aggiungerà la dipendenza al file pyproject.toml del tuo progetto e aggiornerà il uv.lock nella radice.

Quando usi il tuo progetto Python come codice runtime (ad esempio come handler per una funzione AWS lambda), dovrai creare un bundle del codice sorgente e di tutte le sue dipendenze. I generatori py#lambda-function, py#api e py#mcp-server aggiungono questo per te. Per aggiungerne uno manualmente, aggiungi target come il seguente al tuo file project.json, corrispondenti alla forma che quei generatori forniscono:

project.json
{
"targets": {
"bundle": {
"dependsOn": ["bundle-x86"]
},
"bundle-x86": {
"cache": true,
"inputs": ["production", "^production"],
"executor": "nx:run-commands",
"outputs": ["{workspaceRoot}/dist/{projectRoot}/bundle-x86"],
"options": {
"commands": [
"uv export --frozen --no-dev --no-editable --project {projectRoot} --package my_scope.my_library -o dist/{projectRoot}/bundle-x86/requirements.txt",
"uv pip install -n --no-deps --no-installer-metadata --no-compile-bytecode --python-platform x86_64-manylinux_2_28 --python-version 3.14 --target dist/{projectRoot}/bundle-x86 -r dist/{projectRoot}/bundle-x86/requirements.txt"
],
"parallel": false
},
"dependsOn": ["compile"]
}
}
}

Installa le dipendenze Python con il seguente comando:

Finestra del terminale
uv sync

Il tuo progetto Python è configurato con un target build (definito in project.json), che puoi eseguire tramite:

Terminal window
pnpm nx build <project-name>

Dove <project-name> è il nome completamente qualificato del tuo progetto.

Il target build compilerà, eseguirà il lint, testerà e controllerà i tipi del tuo progetto.

L’output della build può essere trovato nella cartella dist nella radice del tuo workspace, all’interno di una directory per il tuo package e target, per esempio dist/packages/<my-library>/build

Per fare la build di tutti i progetti nel tuo workspace, esegui:

Terminal window
pnpm nx run-many --target build

Oppure usa il comando abbreviato:

Terminal window
pnpm build

Il tuo progetto ha anche un target assemble, che produce ciò che il tuo progetto contribuisce a un deployment (ad esempio il suo output compilato o in bundle), senza eseguire i controlli di lint, test o type-check.

Terminal window
pnpm nx assemble <project-name>

I target di deploy dipendono da assemble, quindi il deploy costruisce solo ciò che sta per distribuire.

pytest è configurato per testare il tuo progetto.

I test dovrebbero essere scritti nella directory tests all’interno del tuo progetto, in file python con prefisso test_, per esempio:

  • Directorymy_library
    • my_module.py
  • Directorytests
    • test_my_module.py Tests for my_module.py

I test sono metodi che iniziano con test_ e fanno asserzioni per verificare le aspettative, per esempio:

tests/test_my_module.py
from my_library.my_module import say_hello
def test_say_hello():
assert say_hello("Darth Vader") == "Hello, Darth Vader!"

Per maggiori dettagli su come scrivere test, consulta la documentazione di pytest.

I test verranno eseguiti come parte del target build per il tuo progetto, ma puoi anche eseguirli separatamente eseguendo il target test:

Terminal window
pnpm nx test <project-name>

Puoi eseguire un singolo test o suite di test usando il flag -k, specificando il nome del file di test o del metodo:

Terminal window
pnpm nx test <project-name> -k 'test_say_hello'

La directory tests del tuo progetto è esclusa dall’input denominato production in nx.json.

I target il cui output non può contenere un file di test - come compile e qualsiasi target bundle - leggono production invece di default, quindi modificare un test non li invalida né invalida alcuna attività in un progetto che dipende dal tuo.

L’esclusione è deliberatamente limitata alla directory tests. Un file test_*.py all’interno della directory del tuo package è trattato come codice di produzione, poiché viene impacchettato nella tua distribuzione compilata, e quindi invalida comunque la build.

I target test, lint, format e typecheck leggono default e quindi vengono comunque rieseguiti quando modifichi un test. Nota che typecheck controlla i tipi anche dei tuoi test, quindi un errore di tipo in un test viene comunque segnalato.

I progetti Python usano ty per il controllo dei tipi.

Il controllo dei tipi viene eseguito come parte del target build per il tuo progetto, ma puoi anche eseguirlo separatamente tramite il target typecheck:

Terminal window
pnpm nx run <project-name>:typecheck

Per sopprimere una diagnostica specifica per una singola riga, aggiungi un commento # ty: ignore[<rule>] alla fine della riga, per esempio:

value: int = "not an int" # ty: ignore[invalid-assignment]

Per configurare il comportamento del controllo dei tipi nel tuo progetto, aggiungi una sezione [tool.ty] al pyproject.toml del tuo progetto. Consulta il riferimento di configurazione di ty per le opzioni disponibili.

I progetti Python usano Ruff per il linting.

Per invocare il linter per controllare il tuo progetto, puoi eseguire il target lint.

Terminal window
pnpm nx lint <project-name>

La maggior parte dei problemi di linting o formattazione può essere corretta automaticamente. Puoi dire a Ruff di correggere i problemi di lint eseguendo con l’argomento --configuration=fix.

Terminal window
pnpm nx lint <project-name> --configuration=fix

Allo stesso modo, se desideri correggere tutti i problemi di lint in tutti i package nel tuo workspace, puoi eseguire:

Terminal window
pnpm nx run-many --target lint --all --configuration=fix

Per evitare che i problemi di linting ti rallentino durante lo sviluppo (in particolare se hai problemi non correggibili automaticamente nel tuo progetto), puoi eseguire una build con la configurazione skip-lint:

Terminal window
pnpm nx run-many --target build --configuration=skip-lint

Questo eseguirà comunque Ruff come parte della build, ma il target lint sarà sempre considerato riuscito.