Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 13 additions & 8 deletions .env
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
# TITLE: The title of the FastAPI application
TITLE="FastApi Decorator Builder"
DESCRIPTION="Description de votre API"
ADMIN_EMAIL="deadpool@example.com"
APP_NAME="ChimichangAppAAAAAA"
ITEMS_PER_USER=2
# DESCRIPTION: A description of the API
DESCRIPTION="FastApi Decorator Builder est un algorithme permettant de concevoir un décorateur Python qui transforme
une fonction Python en une API FastAPI. Les fonctionnalités sont accessible suivant une authentification."
# ADMIN_EMAIL: The email address for the admin user of the application
ADMIN_EMAIL="admin@fastApi.com"
# COMMAND_LOAD: The command to start the FastAPI application using uvicorn with automatic reloading
COMMAND_LOAD="python -m uvicorn main:app --reload"
# URL: The base URL of the FastAPI application
URL="http://127.0.0.1:8000"
SAVE_COUNT_FILE="saved_count.txt"
# SAVE_COUNT_FILE: The file name to save the count data
SAVE_COUNT_FILE="saved_count.pki"
# HASH_PASSWORD: A fake hashed password
HASH_PASSWORD="fakehashed"


#ENV="development"
#DATABASE_PASSWORD="motDePasseSecret"
#THIRD_API_PRIVATE_KEY="cleSecrete"
59 changes: 48 additions & 11 deletions Authentification.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from pydantic import BaseModel


# Users database with 2 regular users and 1 administrator
fake_users_db = {
"john": {
"username": "john",
"full_name": "John Doe",
"email": "johndoe@example.com",
"admin": {
"username": "admin",
"full_name": "admin",
"email": "admin@fastApi.com",
"hashed_password": "fakehashedsecret",
"disabled": False,
"admin": True,
Expand All @@ -22,16 +22,29 @@
"disabled": True,
"admin": False,
},
"bod": {
"username": "bod",
"full_name": "bod Wonderson",
"email": "bod@example.com",
"hashed_password": "fakehashedsecret1",
"disabled": False,
"admin": False,
},
}


def fake_hash_password(password: str):
"""
Password hashing function.
:param password: The input password to be hashed.
:return: The hashed password.
"""
return "fakehashed" + password


# OAuth2 password bearer scheme
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")


# Pydantic class to represent the structure of a user
class User(BaseModel):
username: str
email: str = None
Expand All @@ -45,19 +58,33 @@ class UserInDB(User):


def get_user(db, username: str):
"""
Get user from the database.
:param db: The user database.
:param username: The username of the user to retrieve.
:return: An instance of UserInDB if the user exists, otherwise None.
"""
if username in db:
user_dict = db[username]
return UserInDB(**user_dict)


def fake_decode_token(token):
# This doesn't provide any security at all
# Check the next version
"""
function to decode a token.
:param token: The token to be decoded.
:return: An instance of UserInDB if the user exists, otherwise None.
"""
user = get_user(fake_users_db, token)
return user


async def get_current_user(token: Annotated[str, Depends(oauth2_scheme)]):
"""
Get the current user based on the provided token.
:param token: The OAuth2 token.
:return: An instance of UserInDB if the user exists, otherwise raise HTTPException.
"""
user = fake_decode_token(token)
if not user:
raise HTTPException(
Expand All @@ -69,12 +96,22 @@ async def get_current_user(token: Annotated[str, Depends(oauth2_scheme)]):


async def get_current_active_user(current_user: Annotated[User, Depends(get_current_user)]):
"""
Get the current active user based on the current user.
:param current_user: The current user.
:return: The current user if active, otherwise raise HTTPException.
"""
if current_user.disabled:
raise HTTPException(status_code=400, detail="Function not available because you are an Inactive user")
return current_user


async def get_current_admin_user(current_user: Annotated[User, Depends(get_current_user)]):
if current_user.disabled:
raise HTTPException(status_code=400, detail="Function not available because you are an Active user")
"""
Get the current admin user based on the current user.
:param current_user: The current user.
:return:The current user if an admin, otherwise raise HTTPException.
"""
if not current_user.admin:
raise HTTPException(status_code=400, detail="Function not available because you are not an Administrator user")
return current_user
81 changes: 69 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# FastApiDecoratorBuilder
# FastApi Decorator Builder

"FastApiDecoratorBuilder" est un algorithme permettant de concevoir un décorateur Python qui transforme
une fonction Python en une API FastAPI.
"FastApi Decorator Builder" est un algorithme permettant de concevoir un décorateur Python qui transforme
une fonction Python en une API FastAPI. Les fonctionnalités sont accessible suivant une authentification.
L'API permet de collecter des données statisques.

## Installation

Expand All @@ -16,6 +17,7 @@ une fonction Python en une API FastAPI.
6. Un aperçu des requêtes implémentées est disponible à l'adresse suivante : http://127.0.0.1:8000/docs.

## Utilisation
1. Le décorateur
Le décorateur 'fast_api_decorator' ajoute une route avec un endpoint correspondant aux paramètres de la requête
(paramètres de la fonction). Le décorateur appliqué à une fonction puis exécutée sur le même script de l'instance
FastAPI (app) permet de rendre utilisable l'API avec une route qui dépend de la fonction et de ses propres paramètres.
Expand All @@ -25,33 +27,88 @@ L'API est configurée directement grâce aux paramètres du décorateur avec les
les méthodes HTTP (ex: "GET", "POST", "PUT", "DELETE") et une liste de type correspondants aux types des arguments de la
fonction décorée.

## Test
Dans le code suivant, il y a trois fonctions qui ont été implémenté dans l'API. Il suffit d'entrer les points de
terminaison suivants après le lien 'http://127.0.0.1:8000'.

2. L'authentification
Cet API utilise une authentification OAuth2 Password Bearer pour assurer la sécurité des endpoints.
Trois types d'utilisateurs sont définis: administrateur (username : "admin" & password : "secret"), utilisateur régulier
(username : "bod" & password : "secret1") et utilisateur inactif (username : "alice" & password : "secret2").
L'administrateur a accès à toutes les fonctionnalitées proposées par l'API dont les statistiques.
L'utilisateur actif peut utiliser les fonctions mathématiques alors que l'utilisateur inactif ne peut qu'accèder qu'à la
fonctionnalité 'info' de l'API.
Si un token invalide ou si une fonctionnalité réservée à un type d'utilisateur spécifique est renseigné
sans les permissions nécessaires, l'API renverra une erreur :
- 401 Unauthorized: Le token fourni est invalide.
- 400 Bad Request: Vous n'avez pas les permissions nécessaires pour accéder à cette fonctionnalité.


3. Suivi des Statistiques
Les informations telles que le nombre d'appels par route, le temps moyen d'exécution par route sont collectées
automatiquement à chaque appel d'API. -> enregistré dans un fichier .pki

## Fonctionnalités
Dans le code suivant, il y a plusieurs fonctions qui ont été implémenté dans l'API. Certaines fonctions nécéssitent des authentifications.

### Information API
Info
Description : Obtenir des informations sur l'API
Route: '/info/'
Accès : Pas d'accès spécifique

### Opérations Mathématiques
1. Power
Description : Calcul de la puissance d'un nombre
Route: '/power/'
Accès via : Un token d'authentification
Paramètres :
- 'x': Nombre (integer)
- 'a': La puissance (integer)

Exemple : '/power/?x=2&a=3' retournera le résultat de 2 à la puissance 3


2. Add
Description : Calcul l'addition de deux nombres
Route: '/add/'
Accès via : Un token d'authentification
Paramètres :
- 'x': Nombre (integer)
- 'a': Nombre (integer)

Exemple : '/add/?x=2&a=3' retournera la somme de 2 et 3


3. Sous
Description : Calcul la soustraction de trois nombres
Route: '/sous/'
Accès via : Un token d'authentification
Paramètres :
- 'x': Nombre à soustraire (integer)
- [a, b] : liste de nombre (List[int])

Exemple : '/sous/?x=10&lst=3&lst=2' pour soustraire 3 et 2 à 10


4. Div
Description : Calcul la division d'un nombre
Route: '/div/'
Accès via : Un token d'authentification
Paramètres:
- 'x': Numérateur(integer)
- item: Modèle Pydantic contenant le diviseur

### Gestion des Utilisateurs
User
Description : Obtenir des informations sur l'utilisateur actuel
Route: '/users/me'
Accès via : Un token d'authentification

### Obtention d'un token
Token
Description : Obtenir le jeton d'accès
Route: '/token/'
Paramètres:
- 'username': Nom d'utilisateur
- 'password': Mot de passe

### Statistiques
Stats
Description : Obtenir le jeton d'accès
Route: '/stats/'
Accès via : Un token d'authentification d'administrateur


## Compte rendu du projet
Expand Down
Loading