FastAPI vers Base de données relationnelle
Le générateur connection relie un projet FastAPI à un projet Python Relational Database, en injectant une session SQLModel typée dans vos gestionnaires de routes via une dépendance FastAPI.
Prérequis
Section intitulée « Prérequis »Avant d’utiliser ce générateur, assurez-vous d’avoir :
Utilisation
Section intitulée « Utilisation »Exécuter le générateur
Section intitulée « Exécuter le générateur »pnpm nx g @aws/nx-plugin:connectionyarn nx g @aws/nx-plugin:connectionnpx nx g @aws/nx-plugin:connectionbunx nx g @aws/nx-plugin:connectionVous pouvez également effectuer une simulation pour voir quels fichiers seraient modifiés
pnpm nx g @aws/nx-plugin:connection --dry-runyarn nx g @aws/nx-plugin:connection --dry-runnpx nx g @aws/nx-plugin:connection --dry-runbunx nx g @aws/nx-plugin:connection --dry-run- Installez le Nx Console VSCode Plugin si ce n'est pas déjà fait
- Ouvrez la console Nx dans VSCode
- Cliquez sur
Generate (UI)dans la section "Common Nx Commands" - Recherchez
@aws/nx-plugin - connection - Remplissez les paramètres requis
- Cliquez sur
Generate
Sélectionnez votre projet FastAPI comme source et votre projet de base de données relationnelle comme cible.
| Paramètre | Type | Par défaut | Description |
|---|---|---|---|
| sourceProject Requis | string | - | Le projet source |
| targetProject Requis | string | - | Le projet cible auquel se connecter |
| sourceComponent | string | - | Le composant source depuis lequel se connecter (nom du composant, chemin relatif à la racine du projet source, ou identifiant du générateur). Utilisez '.' pour sélectionner explicitement le projet comme source. |
| targetComponent | string | - | Le composant cible auquel se connecter (nom du composant, chemin relatif à la racine du projet cible, ou identifiant du générateur). Utilisez '.' pour sélectionner explicitement le projet comme cible. |
| preferInstallDependencies | boolean | true | Indique s'il faut privilégier l'installation des dépendances après l'exécution du générateur. Définir à false pour différer l'installation lors de l'exécution de plusieurs générateurs en lot (une installation s'exécute quand même si nécessaire pour que les générateurs suivants puissent calculer le graphe de projet Nx) ; installer une seule fois à la fin. |
Sortie du générateur
Section intitulée « Sortie du générateur »Le générateur modifie votre projet FastAPI :
Répertoirepackages/my_api
- project.json Ajoute une dépendance de
devsur la cibledevde la base de données - pyproject.toml Ajoute le package de base de données comme dépendance d’espace de travail
Répertoiremy_api
Répertoiredependencies
- my_db.py Dépendance FastAPI
MyDbSessionpour la session de base de données
- my_db.py Dépendance FastAPI
- project.json Ajoute une dépendance de
Utiliser la base de données dans les gestionnaires de routes
Section intitulée « Utiliser la base de données dans les gestionnaires de routes »Ce générateur configure une dépendance FastAPI injectable que vous pouvez utiliser dans vos gestionnaires de routes :
from sqlmodel import selectfrom my_api.dependencies.my_db import MyDbSessionfrom my_scope.my_db.models.example import ExampleModel
@app.get("/examples")async def list_examples(my_db: MyDbSession): return (await my_db.execute(select(ExampleModel))).all()
@app.post("/examples")async def create_example(name: str, my_db: MyDbSession): item = ExampleModel(name=name) my_db.add(item) await my_db.commit() await my_db.refresh(item) return itemFastAPI ouvre automatiquement une nouvelle session par requête et la ferme lorsque le gestionnaire retourne.
Infrastructure
Section intitulée « Infrastructure »Pour permettre à la fonction Lambda FastAPI de se connecter à la base de données lors de l’exécution, elle doit être déployée dans le même VPC que la base de données et bénéficier d’un accès réseau et IAM.
Dans votre stack d’application, déployez l’API dans le même VPC que la base de données, puis appelez allowDefaultPortFrom et grantConnect pour ouvrir le chemin réseau et accorder la permission IAM rds-db:connect au gestionnaire Lambda :
import { MyDatabase } from '@my-scope/common-constructs';
const db = new MyDatabase(this, 'Db', { vpc, ... });
const api = new MyApi(this, 'Api', { integrations: MyApi.defaultIntegrations(this) .withDefaultOptions({ vpc, vpcSubnets: { subnetType: SubnetType.PRIVATE_WITH_EGRESS }, }) .build(),});
Object.entries(api.integrations).forEach(([operation, integration]) => { db.allowDefaultPortFrom(integration.handler, `Allow ${operation} to connect to the database`); db.grantConnect(integration.handler);});Déployez les fonctions Lambda de l’API dans un sous-réseau privé avec sortie, et non dans un sous-réseau privé isolé. Lors de l’exécution, session_context() récupère la configuration de la base de données depuis AWS AppConfig, qui est un point de terminaison de service AWS public nécessitant un accès Internet sortant.
Déployez l’API dans le même VPC que la base de données, accordez-lui rds-db:connect via additional_iam_policy_statements, et ouvrez le chemin réseau avec une paire de règles de groupe de sécurité :
L’exemple ci-dessous fait référence aux ressources VPC du guide de déploiement Python Relational Database : les sous-réseaux aws_subnet.database n’ont pas de route Internet, tandis que les sous-réseaux aws_subnet.private ont une sortie NAT.
module "my_database" { source = "../../common/terraform/src/app/dbs/my-database" vpc_id = aws_vpc.main.id database_subnet_ids = aws_subnet.database[*].id lambda_subnet_ids = aws_subnet.private[*].id}
module "api" { source = "../../common/terraform/src/app/apis/my-api" enable_vpc = true vpc_id = aws_vpc.main.id subnet_ids = aws_subnet.private[*].id
appconfig_application_id = module.runtime_config_appconfig.application_id appconfig_application_arn = module.runtime_config_appconfig.application_arn
additional_iam_policy_statements = [ { Effect = "Allow" Action = ["rds-db:connect"] Resource = [ "arn:aws:rds-db:${data.aws_region.current.region}:${data.aws_caller_identity.current.account_id}:dbuser:${module.my_database.connect_resource_id}/${module.my_database.database_runtime_user}" ] } ]}
resource "aws_vpc_security_group_ingress_rule" "api_to_database" { description = "Allow the API Lambda functions to connect to the database" security_group_id = module.my_database.security_group_id referenced_security_group_id = module.api.security_group_id from_port = module.my_database.cluster_port to_port = module.my_database.cluster_port ip_protocol = "tcp"}
resource "aws_vpc_security_group_egress_rule" "api_to_database" { description = "Allow outbound traffic from the API Lambda functions to the database" security_group_id = module.api.security_group_id referenced_security_group_id = module.my_database.security_group_id from_port = module.my_database.cluster_port to_port = module.my_database.cluster_port ip_protocol = "tcp"}Déployez les fonctions Lambda de l’API dans des sous-réseaux privés avec sortie, et non dans des sous-réseaux privés isolés. appconfig_application_id/appconfig_application_arn proviennent de l’application AppConfig de configuration d’exécution partagée déclarée une fois dans votre module racine, et non du module de base de données — les transmettre définit RUNTIME_CONFIG_APP_ID sur les fonctions Lambda et leur accorde un accès en lecture à l’application.
L’application AppConfig doit exposer l’espace de noms database pour que l’entrée de configuration d’exécution du module de base de données soit déployée. Incluez-le dans les namespaces lors de l’instanciation du module runtime-config/appconfig :
module "runtime_config_appconfig" { source = "../../common/terraform/src/core/runtime-config/appconfig"
application_name = "my-app-runtime-config" namespaces = ["connection", "agentcore", "database"]}Développement local
Section intitulée « Développement local »pnpm nx dev <project-name>yarn nx dev <project-name>npx nx dev <project-name>bunx nx dev <project-name>Cela démarre la FastAPI et toutes les bases de données connectées. La variable d’environnement LOCAL_DEV=true fait en sorte que le client de base de données se connecte à sa base de données Docker locale au lieu d’Aurora.