Demosthene-OR commited on
Commit
5afe693
1 Parent(s): 40486e6

complement

Browse files
Files changed (7) hide show
  1. Dockerfile +1 -1
  2. app.py +0 -189
  3. credentials.csv +0 -95
  4. main.py +183 -0
  5. openapi.json +1 -0
  6. questions.csv +78 -0
  7. requirements.txt +21 -4
Dockerfile CHANGED
@@ -8,4 +8,4 @@ RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
8
 
9
  COPY . .
10
 
11
- CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "7860"]
 
8
 
9
  COPY . .
10
 
11
+ CMD ["uvicorn", "app.main:api", "--host", "0.0.0.0", "--port", "7860"]
app.py DELETED
@@ -1,189 +0,0 @@
1
- from flask import Flask, request, jsonify, make_response
2
- from flasgger import Swagger, swag_from
3
- from vaderSentiment.vaderSentiment import SentimentIntensityAnalyzer
4
- import random
5
- import csv
6
-
7
- app = Flask(__name__)
8
- swagger = Swagger(app)
9
-
10
- # Définition du titre de la documentation Swagger
11
- app.config['SWAGGER'] = {
12
- 'title': 'API Analyse de sentiment',
13
- 'description': 'Documentation de l\'API pour l\'analyse de sentiment',
14
- 'version': '1.0.0'
15
- }
16
-
17
- # Charger les informations d'authentification à partir du fichier credentials.csv
18
- def load_credentials(file_path):
19
- credentials = {}
20
- with open(file_path, newline='') as csvfile:
21
- reader = csv.DictReader(csvfile)
22
- for row in reader:
23
- credentials[row['username']] = {'password': row['password'], 'v1': int(row['v1']), 'v2': int(row['v2'])}
24
- return credentials
25
-
26
- credentials = load_credentials('credentials.csv')
27
-
28
- # Route pour vérifier l'état de l'API
29
- @app.route('/status')
30
- def status():
31
- """
32
- API Status
33
- ---
34
- responses:
35
- 200:
36
- description: API is working
37
- examples:
38
- message: 1
39
- """
40
- return '1'
41
-
42
-
43
-
44
- # Route pour saluer l'utilisateur
45
- @app.route('/welcome')
46
- def welcome():
47
- """
48
- Message de bienvenue
49
- ---
50
- parameters:
51
- - name: username
52
- in: query
53
- type: string
54
- required: true
55
- description: Message de bienvenue à l'utilisateur
56
- responses:
57
- 200:
58
- description: Message
59
- examples:
60
- message: Bienvenue sur l'API d'Analyse de sentiment, Olivier!
61
- """
62
- username = request.args.get('username')
63
- return f"Bienvenue sur l'API d'Analyse de sentiment {username}!"
64
-
65
-
66
-
67
- # Route pour vérifier les credentials de l'utilisateur
68
- @app.route('/credentials', methods=['POST'])
69
- def check_credentials():
70
- """
71
- credentials Route
72
- ---
73
- consumes:
74
- - application/json
75
- parameters:
76
- - in: header
77
- name: Authorization
78
- type: string
79
- required: true
80
- description: The user's credentials in the format "username=password"
81
- responses:
82
- 200:
83
- description: A list of user credentials
84
- examples:
85
- username: John
86
- v1: 1
87
- v2: 0
88
- """
89
- auth = request.headers.get('Authorization')
90
- if not auth:
91
- return 'Unauthorized', 401
92
-
93
- username, password = auth.split('=')
94
- if username not in credentials or credentials[username]['password'] != password:
95
- return 'Unauthorized', 401
96
-
97
- response_data = {'username': username, 'v1': credentials[username]['v1'], 'v2': credentials[username]['v2']}
98
- response = make_response(jsonify(response_data), 200)
99
- response.headers['Content-Type'] = 'application/json'
100
- return response
101
-
102
-
103
- # Route pour l'analyse de sentiment avec le modèle v1
104
- @app.route('/v1/sentiment', methods=['POST'])
105
- def sentiment_v1():
106
- """
107
- Sentiment Analysis Route (Model v1)
108
- ---
109
- parameters:
110
- - in: header
111
- name: Authorization
112
- type: string
113
- required: true
114
- description: The user's credentials in the format "username=password"
115
- - in: formData # Modification ici pour spécifier le type de données du formulaire
116
- name: sentence
117
- type: string
118
- required: true
119
- description: The sentence to analyze
120
- responses:
121
- 200:
122
- description: The sentiment score
123
- examples:
124
- score: 0.5
125
- """
126
- auth = request.headers.get('Authorization')
127
- if not auth:
128
- return 'Unauthorized', 401
129
-
130
- username, password = auth.split('=')
131
- if username not in credentials or credentials[username]['password'] != password:
132
- return 'Unauthorized (wrong username and/or password)', 401
133
-
134
- if credentials[username]['v1']==0:
135
- return 'User unauthorized for Sentiment Analysis v1', 401
136
-
137
- sentence = request.form.get('sentence')
138
- if not sentence:
139
- return 'Bad Request', 400
140
-
141
- # Implémentation factice de l'analyse de sentiment pour le modèle v1 (nombre aléatoire entre -1 et 1)
142
- sentiment_score = random.uniform(-1, 1)
143
- return str(sentiment_score)
144
-
145
- # Route pour l'analyse de sentiment avec le modèle v2
146
- @app.route('/v2/sentiment', methods=['POST'])
147
- def sentiment_v2():
148
- """
149
- Sentiment Analysis Route (Model v2)
150
- ---
151
- parameters:
152
- - in: header
153
- name: Authorization
154
- type: string
155
- required: true
156
- description: The user's credentials in the format "username=password"
157
- - in: formData # Modification ici pour spécifier le type de données du formulaire
158
- name: sentence
159
- type: string
160
- required: true
161
- description: The sentence to analyze
162
- responses:
163
- 200:
164
- description: The sentiment score
165
- examples:
166
- score: 0.5
167
- """
168
- auth = request.headers.get('Authorization')
169
- if not auth:
170
- return 'Unauthorized', 401
171
-
172
- username, password = auth.split('=')
173
- if username not in credentials or credentials[username]['password'] != password:
174
- return 'Unauthorized (wrong username and/or password)', 401
175
-
176
- if credentials[username]['v2']==0:
177
- return 'User unauthorized for Sentiment Analysis v2', 401
178
-
179
- sentence = request.form.get('sentence')
180
- if not sentence:
181
- return 'Bad Request', 400
182
-
183
- # Implémentation de l'analyse de sentiment avec le modèle v2 (VaderSentiment)
184
- analyzer = SentimentIntensityAnalyzer()
185
- sentiment_score = analyzer.polarity_scores(sentence)['compound']
186
- return str(sentiment_score)
187
-
188
- if __name__ == '__main__':
189
- app.run(host="0.0.0.0",debug=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
credentials.csv DELETED
@@ -1,95 +0,0 @@
1
- username,password,v1,v2
2
- Quinlan,5210,0,1
3
- Davis,5783,0,0
4
- Montana,3134,0,0
5
- Quintessa,8790,0,1
6
- Camden,4837,0,0
7
- Megan,6837,1,1
8
- Liberty,5564,1,1
9
- Zelda,8610,0,1
10
- Mara,9820,1,0
11
- Steven,5998,1,1
12
- Rhiannon,3545,1,0
13
- Julian,7520,0,1
14
- Anika,8944,0,1
15
- Justine,9156,1,0
16
- Lionel,4527,0,1
17
- Yoshi,4237,1,1
18
- Brian,7263,1,1
19
- Leila,8308,0,1
20
- Piper,2914,1,0
21
- Yen,3932,1,0
22
- Amber,9274,1,1
23
- Rhonda,6818,1,0
24
- Lamar,6478,0,0
25
- Nolan,4611,1,1
26
- Ulla,3610,0,1
27
- Ginger,6723,0,1
28
- Geraldine,5725,0,1
29
- Dominic,7914,1,1
30
- Paula,8403,1,0
31
- Hashim,7658,1,1
32
- Demetria,2132,1,1
33
- Wang,7829,1,0
34
- Tyler,4453,0,0
35
- Kim,7134,0,1
36
- Edward,1871,1,1
37
- Russell,3039,0,0
38
- Malachi,5226,1,0
39
- Barrett,2891,1,0
40
- Harriet,6877,0,0
41
- Portia,8105,0,0
42
- Raya,3006,1,1
43
- Reed,1745,0,1
44
- Penelope,4844,1,0
45
- Whilemina,6551,1,1
46
- Fay,9208,0,0
47
- Shad,4903,0,0
48
- Pandora,2598,1,1
49
- Abbot,3545,0,0
50
- Ciaran,2336,0,1
51
- Nehru,8209,1,0
52
- Logan,9622,0,1
53
- Vernon,1422,0,1
54
- Gavin,9632,0,1
55
- Dana,5425,1,0
56
- Ashton,1128,0,0
57
- Mark,4608,1,1
58
- Akeem,7908,0,0
59
- Richard,2816,1,1
60
- Colby,2427,1,1
61
- Yasir,9460,1,0
62
- Octavia,6792,1,1
63
- Noel,3409,0,1
64
- Michael,3341,0,0
65
- Joel,3447,0,1
66
- Stacy,9140,1,0
67
- Mason,6588,1,1
68
- Kelsey,3801,0,1
69
- Daria,3036,1,1
70
- Joy,1306,1,1
71
- Xantha,8532,0,0
72
- Lael,4088,1,1
73
- Ursa,5331,1,0
74
- Hayes,5297,0,1
75
- Neve,4972,1,0
76
- Bradley,6463,1,1
77
- Sonya,7745,0,0
78
- Adam,5910,0,1
79
- Alfonso,8611,1,1
80
- Jin,4199,0,1
81
- Jared,2126,0,0
82
- Constance,6624,1,1
83
- Myra,2262,1,1
84
- Emerald,5253,0,0
85
- Remedios,2766,1,1
86
- Shannon,2704,0,0
87
- Steel,2034,1,0
88
- Xena,7153,1,0
89
- Ann,3068,0,1
90
- Hadassah,3371,0,1
91
- Xavier,8313,0,0
92
- Hall,5494,1,0
93
- Conan,3708,0,0
94
- Buffy,5225,1,0
95
- Chava,2094,0,1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
main.py ADDED
@@ -0,0 +1,183 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, HTTPException, Header, Depends, Request
2
+ from fastapi.responses import JSONResponse
3
+ from fastapi.security import HTTPBasic, HTTPBasicCredentials
4
+ from fastapi.exceptions import RequestValidationError
5
+ from typing import Optional, List
6
+ from pydantic import BaseModel, ValidationError
7
+ import pandas as pd
8
+ import datetime
9
+
10
+ api = FastAPI()
11
+
12
+ # Charger les données à partir du fichier CSV
13
+ questions_data = pd.read_csv('questions.csv')
14
+
15
+ # Dictionnaire des identifiants des utilisateurs
16
+ users_credentials = {
17
+ "alice": "wonderland",
18
+ "bob": "builder",
19
+ "clementine": "mandarine",
20
+ "admin": "4dm1N" # Ajout de l'utilisateur admin
21
+ }
22
+
23
+ # Modèle Pydantic pour représenter une question
24
+ class Question(BaseModel):
25
+ question: str
26
+ subject: str
27
+ correct: Optional[str] = None # Champ optionnel
28
+ use: str
29
+ responseA: str
30
+ responseB: str
31
+ responseC: Optional[str] = None # Champ optionnel
32
+ responseD: Optional[str] = None # Champ optionnel
33
+ # remark: Optional[str] = None # Champ optionnel
34
+
35
+ # Modèle pour représenter une exception personnalisée
36
+ class MyException(Exception):
37
+ def __init__(self,
38
+ status_code: int,
39
+ name : str,
40
+ message : str):
41
+ self.status_code = status_code
42
+ self.name = name
43
+ self.message = message
44
+ self.date = str(datetime.datetime.now())
45
+
46
+ # Gestionnaire d'exception personnalisé
47
+ @api.exception_handler(MyException)
48
+ def MyExceptionHandler(
49
+ request: Request,
50
+ exception: MyException
51
+ ):
52
+ return JSONResponse(
53
+ status_code=exception.status_code,
54
+ content={
55
+ 'url': str(request.url),
56
+ 'name': exception.name,
57
+ 'message': exception.message,
58
+ 'date': exception.date
59
+ }
60
+ )
61
+
62
+ # Gestionnaire d'exception pour les erreurs de validation de la requête
63
+ @api.exception_handler(RequestValidationError)
64
+ async def validation_exception_handler(request: Request, exc: RequestValidationError):
65
+ return JSONResponse(
66
+ status_code=422,
67
+ content={
68
+ 'url': str(request.url),
69
+ 'name': "Erreur de validation de la requête (parametre requis)",
70
+ 'message': exc.errors(),
71
+ 'date': str(datetime.datetime.now())
72
+ },
73
+ )
74
+
75
+ # Gestionnaire d'exception pour les erreurs Pydantic
76
+ @api.exception_handler(ValidationError)
77
+ async def validation_exception_handler(request: Request, exc: ValidationError):
78
+ return JSONResponse(
79
+ status_code=422,
80
+ content={
81
+ 'url': str(request.url),
82
+ 'name': "Erreur de validation Pydantic",
83
+ 'message': exc.errors(),
84
+ 'date': str(datetime.datetime.now())
85
+ },
86
+ )
87
+
88
+
89
+ # Fonction pour vérifier l'authentification de l'utilisateur
90
+ def authenticate(authorization: str = Header(None)):
91
+ if not authorization:
92
+ raise HTTPException(status_code=401, detail="Utilisateur non authorisé")
93
+ try:
94
+ scheme, credentials = authorization.split()
95
+ if scheme != 'Basic':
96
+ raise HTTPException(status_code=401, detail="Utilisateur non authorisé")
97
+ username, password = credentials.split(":")
98
+ if username not in users_credentials or users_credentials[username] != password:
99
+ raise HTTPException(status_code=401, detail="Utilisateur non authorisé")
100
+ except Exception as e:
101
+ raise HTTPException(status_code=401, detail="Utilisateur non authorisé")
102
+ return username, password
103
+
104
+ # Endpoint pour vérifier que l'API est fonctionnelle
105
+ @api.get('/', name="Vérification que l'API fonctionne")
106
+ def check_api():
107
+ return {'message': "L'API fonctionne"}
108
+
109
+ # Endpoint pour récupérer les questions en fonction du type de test (use) et des catégories (subject) spécifiés
110
+ @api.get('/questions', name="Récupération des questions pour un QCM")
111
+ def get_questions(use: str,
112
+ subject: str,
113
+ num_questions: int,
114
+ auth_info: tuple = Depends(authenticate)):
115
+ """
116
+ Récupère les questions en fonction du type de test (use) et des catégories (subject) spécifiés
117
+ L'application peut produire des QCMs de 5, 10 ou 20 questions (seulement)
118
+ Les questions sont retournées dans un ordre aléatoire
119
+ Seuls les utilisateurs se trouvant dans users_credentials peuvent utiliser cette application
120
+ """
121
+
122
+ # Verifier si le nombre de questions demandé correspond au nombre de questions d'un QCM
123
+ if num_questions not in [5,10,20]:
124
+ raise MyException(status_code=422, name="num_questions invalide", \
125
+ message="La requête peut contenir 51,10 ou 20 questions, mais pas "+str(num_questions))
126
+
127
+ # Filtrer les questions en fonction des paramètres spécifiés
128
+ filtered_questions = questions_data
129
+ if use:
130
+ filtered_questions = filtered_questions[filtered_questions['use'] == use]
131
+ if subject is not None:
132
+ s = subject.split(',')
133
+ filtered_questions = filtered_questions[filtered_questions['subject'].isin(s)]
134
+ print("len(filtered_questions)=",len(filtered_questions))
135
+ print("num_questions=",num_questions)
136
+ # Vérifier si des questions sont disponibles dans la catégorie spécifiée
137
+ if len(filtered_questions) == 0:
138
+ raise MyException(status_code=404, name="Aucune question", \
139
+ message="Aucune question ne correspond aux critères sélectionnés")
140
+ # Verifier si le nombre de questions diponibles >= au nombre requis
141
+ elif (len(filtered_questions) < num_questions):
142
+ raise MyException(status_code=400, name="Nb insuffisant de questions ", \
143
+ message="Le nombre de questions correspondantes aux critères sélectionnés est < au nombre requis")
144
+
145
+ # Supprimer les valeurs NaN dans les champs correct,responseC, responseD (ils ne sont pas toujours remplis)
146
+ filtered_questions['correct'] = filtered_questions['correct'].apply(lambda x: None if pd.isna(x) else x)
147
+ filtered_questions['responseC'] = filtered_questions['responseC'].apply(lambda x: None if pd.isna(x) else x)
148
+ filtered_questions['responseD'] = filtered_questions['responseD'].apply(lambda x: None if pd.isna(x) else x)
149
+
150
+ # Sélectionner un nombre aléatoire de questions
151
+ selected_questions = filtered_questions.sample(n=min(num_questions, len(filtered_questions)))
152
+
153
+ # Convertir les données en liste de dictionnaires
154
+ questions_list = selected_questions.to_dict(orient='records')
155
+
156
+ # Convertir les dictionnaires en objets Pydantic de type Question
157
+ questions_objects = [Question(**question) for question in questions_list]
158
+ return questions_objects
159
+
160
+
161
+ # Endpoint pour créer une nouvelle question (accessible uniquement par l'utilisateur admin)
162
+ @api.post('/questions/create', name="Création d'une nouvelle question")
163
+ def create_question(question: Question,
164
+ auth_info: tuple = Depends(authenticate)):
165
+ """
166
+ Crée une nouvelle question et l'ajoute à questions.csv
167
+ Seuls l' utilisateur admin a le droit d'utiliser cette fonction
168
+ """
169
+ global questions_data
170
+
171
+ username, password = auth_info
172
+ if username != 'admin':
173
+ raise HTTPException(status_code=401, detail="Utilisateur non authorisé")
174
+
175
+ # Ajouter la nouvelle question au DataFrame
176
+ new_question = question.model_dump()
177
+ questions_data = questions_data.append(new_question, ignore_index=True)
178
+
179
+ # Sauvegarder les modifications dans le fichier CSV
180
+ questions_data.to_csv('questions.csv', index=False)
181
+
182
+ return {'message': 'Question créée avec succès'}
183
+
openapi.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"openapi":"3.1.0","info":{"title":"FastAPI","version":"0.1.0"},"paths":{"/":{"get":{"summary":"Vérification Que L'Api Fonctionne","operationId":"Vérification_que_l_API_fonctionne__get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/questions":{"get":{"summary":"Récupération Des Questions Pour Un Qcm","description":"Récupère les questions en fonction du type de test (use) et des catégories (subject) spécifiés\nL'application peut produire des QCMs de 5, 10 ou 20 questions (seulement)\nLes questions sont retournées dans un ordre aléatoire\nSeuls les utilisateurs se trouvant dans users_credentials peuvent utiliser cette application","operationId":"Récupération_des_questions_pour_un_QCM_questions_get","security":[{"HTTPBasic":[]}],"parameters":[{"name":"use","in":"query","required":true,"schema":{"type":"string","title":"Use"}},{"name":"subject","in":"query","required":true,"schema":{"type":"string","title":"Subject"}},{"name":"num_questions","in":"query","required":true,"schema":{"type":"integer","title":"Num Questions"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/questions/create":{"post":{"summary":"Création D'Une Nouvelle Question","description":"Crée une nouvelle question et l'ajoute à questions.csv\nSeuls l' utilisateur admin a le droit d'utiliser cette fonction","operationId":"Création_d_une_nouvelle_question_questions_create_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Question"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBasic":[]}]}}},"components":{"schemas":{"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"Question":{"properties":{"question":{"type":"string","title":"Question"},"subject":{"type":"string","title":"Subject"},"correct":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Correct"},"use":{"type":"string","title":"Use"},"responseA":{"type":"string","title":"Responsea"},"responseB":{"type":"string","title":"Responseb"},"responseC":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Responsec"},"responseD":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Responsed"}},"type":"object","required":["question","subject","use","responseA","responseB"],"title":"Question"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}},"securitySchemes":{"HTTPBasic":{"type":"http","scheme":"basic"}}}}
questions.csv ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ question,subject,use,correct,responseA,responseB,responseC,responseD,remark
2
+ Que signifie le sigle No-SQL ?,BDD,Test de positionnement,A,Pas seulement SQL,Pas de SQL,Pas tout SQL,,
3
+ Cassandra et HBase sont des bases de données,BDD,Test de positionnement,C,relationnelles,orientées objet,orientées colonne,orientées graphe,
4
+ MongoDB et CouchDB sont des bases de données,BDD,Test de positionnement,B,relationnelles,orientées objet,orientées colonne,orientées graphe,
5
+ OrientDB et Neo4J sont des bases de données,BDD,Test de positionnement,D,relationnelles,orientées objet,orientées colonne,orientées graphe,
6
+ "Pour indexer des données textuelles, je peux utiliser",BDD,Test de positionnement,A,ElasticSearch,Neo4J,MySQL,,
7
+ A quoi faire attention lorsqu'on choisit un système de base de données ?,BDD,Test de positionnement,D,La définition d'un schéma,La rapidité de lecture/écriture,La différenciation des accés,Tous ces points,
8
+ Quels sont les trois éléments constitutifs de Hadoop ?,Systèmes distribués,Test de positionnement,A,"HDFS, YARN et Haddoop MapReduce","Hive, LOL et Spark","Spark, Hadoop MapReduce et Hive",,
9
+ "Lors de l'étape de Map d'un wordcount appliqué à la phrase ""cette phrase est une phrase"", les valeurs émises sont:",Systèmes distribués,Test de positionnement,B,"1, 2, 1, 1","1, 1, 1, 1, 1, 1","5, 0, 0, 0, 0",,
10
+ "Dans Hadoop, les combiners permettent",Systèmes distribués,Test de positionnement,C,de combiner les entrées et les sorties,de mieux distribuer la charge lors de la phase de Shuffle,de limiter le nombre de valeurs émises lors de l'étape de Reduce,,
11
+ "Dans Hadoop, les partitioners permettent",Systèmes distribués,Test de positionnement,B,de combiner les entrées et les sorties,de mieux distribuer la charge lors de la phase de Shuffle,de limiter le nombre de valeurs émises lors de l'étape de Reduce,,
12
+ Le théorème CAP oppose,Systèmes distribués,Test de positionnement,B,"Capacité, Vitesse, Distribution","Disponibilité, Cohérence, Distribution","Cohérence, Adaptabilité, Puissance",,
13
+ Hive permet,Systèmes distribués,Test de positionnement,A,d'abstraire une base de données relationnelle,de classer les documents par ordre d'importance,d'orchestrer des clusters de machine,,
14
+ Spark se différencie de Hadoop par,Systèmes distribués,Test de positionnement,D,son absence de système de stockage,ses nombreuses librairies notamment de Machine Learning,l'écriture en mémoire plutôt que sur disque lors de la phase de Shuffle,Tous ces points,
15
+ Un système de messagerie asynchrone permet de décorréler les consommateurs et les producteurs,Streaming de données,Test de positionnement,A,Vrai,Faux,,,
16
+ Kafka est système de messagerie,Streaming de données,Test de positionnement,D,distribué,asynchrone,publication/abonnement,Tous ces points,
17
+ L'architecture lambda présente les couches,Streaming de données,Test de positionnement,D,batch,temps réel,service,Tous ces points,
18
+ Docker est utilisé,Docker,Test de positionnement,A,pour développer rapidement et mettre en production facilement,pour améliorer les capacités d'une base de données,pour améliorer la puissance de calcul,,
19
+ Docker permet de persister des changements,Docker,Test de positionnement,C,Oui,Non,Oui à condition d'utiliser des volumes,,
20
+ Des containers Docker peuvent communiquer entre eux grâce à,Docker,Test de positionnement,B,des volumes,des networks,des communications ,,
21
+ DockerHub est,Docker,Test de positionnement,C,un système qui permet de lancer plusieurs containers d'un coup,un système d'orchestration de containers,un répertoire d'images Docker,,
22
+ Docker-compose est ,Docker,Test de positionnement,A,un système qui permet de lancer plusieurs containers d'un coup,un système d'orchestration de containers,un répertoire d'images Docker,,
23
+ Lequel de ces problème est un problème de classification:,Classification,Test de validation,C,Segmentation clients,Calcul de prix optimal,Prédiction du caractère bénin d’une tumeur,,
24
+ Lequel de ces problème est un problème de classification,Classification,Test de validation,B,Estimation du prix d’une oeuvre d’art,Prédiction du départ d’un client,Modélisation des flux d’air autour d’un réacteur,,
25
+ Lequel de ces problème est un problème de classification,Classification,Test de validation,"B,C",Labellisation d’une image,Reconnaissance d’objet,Génération automatique de mots,,
26
+ Est-ce que les algorithmes de classification permettent de donner une probabilité d’appartenance à une classe plutôt que simplement l’étiquette?,Classification,Test de validation,A,"Oui, c’est en général la base de tous les algorithmes de classification","Non, ce problème est un problème de régression",,,
27
+ Quelle métrique est utilisée en classification ?,Classification,Test de validation,A,Le F1-score,Le RMSE,La perplexité,,
28
+ Quel algorithme est mieux adapté à un jeu de données majoritairement composé de variables qualitatives?,Classification,Test de validation,C,SVM,Régression Logistique,Arbre de décision,,
29
+ "Dans un problème de fraude bancaire, la précision est-elle une métrique adaptée?
30
+ ",Classification,Test de validation,B,Oui puisque c’est un problème de classification.,Non car le déséquilibre des deux classes ne permet pas une amélioration significative de cette métrique,,,
31
+ De donner une meilleure métrique dans toutes les situations,Classification,Test de validation,C,De donner une meilleure métrique dans toutes les situations,D’être plus facilement interprétable ,D’identifier facilement des proportions d’observations en fonction de leur probabilité,,
32
+ "La spécificité est définie par (V: vrai, F: faux, P: positif, N: négatif) : ",Classification,Test de validation,B,(VP + VN) / (VP + VN + FN + FP),VN / (VN + FP),VP / (VP + FN),,
33
+ "La sensibilité est définie par (V: vrai, F: faux, P: positif, N: négatif) : ",Classification,Test de validation,C,(VP + VN) / (VP + VN + FN + FP),VN / (VN + FP),VP / (VP + FN),,
34
+ Hadoop permet de: ,Systèmes distribués,Test de validation,D,Stocker des données,Faire des calculs,Orchestrer des jobs MapReduce,Tous ces points,
35
+ "Dans le paradigme MapReduce, les combiners servent à: ",Systèmes distribués,Test de validation,B,Équilibrer la charge de travail des reducers,Diminuer le nombre de valeurs à émettre des mappers aux reducers,Accélérer les calculs,Tous ces points,
36
+ "Dans le paradigme MapReduce, les partitioners servent à: ",Systèmes distribués,Test de validation,A,Équilibrer la charge de travail des reducers,Diminuer le nombre de valeurs à émettre des mappers aux reducers,Accélérer les calculs,Tous ces points,
37
+ L'utilisation de systèmes distrubués permet,Systèmes distribués,Test de validation,D,D'accélérer les calculs ,De sécuriser l'accés aux données,D'augmenter facilement la capacité de stockage,Tous ces points,
38
+ Hadoop streaming est un outil qui permet,Systèmes distribués,Test de validation,A,De faire des jobs MapReduce avec n'importe quel langage de programmation,De faire du traitement de données en temps réel ,De stocker plusieurs copies d'un jeu de données,De stocker des vidéos sur un système distribué,
39
+ "Dans le cas d'une architecture distribuée, le théorème CAP nous oblige à choisir entre:",Systèmes distribués,Test de validation,A,Cohérence et Disponibilité,Partition et Cohérence,Partition et Disponibilité,,
40
+ Hive est ,Sytèmes distribués,Test de validation,B,Un système de gestion de bases de données relationnelles,Une abstraction de SGDB relationnelles,Une librairie de Hadoop,,
41
+ "Pour Hive, partitioner consiste à ",Systèmes distribués,Test de validation,C,Découper les tables en block de taille pré-définie,Découper les tables par colonnes,Découper les tables selon les valeurs d'une variable,,
42
+ Pig permet,Systèmes distribués,Test de validation,A,De rendre l'écriture de jobs MapReduce plus simple et plus intuitive,D'accélérer les calculs effectués sur Hadoop ,D'orchestrer Hive,Tous ces points,
43
+ Sqoop est utilisé,Systèmes distribués,Test de validation,A,Pour transférer des données depuis des SGDBR vers HDFS et inversement,De faire des calculs en temps réel ,D'automatiser des jobs Map Reduce,Tous ces points,
44
+ Data science is ...,Data Science,Total Bootcamp,A,A set of techniques and tools used to get value out of data.,A scientific approach of data acquisition.,A set of empirical approachs used to define theoretical formulas and /or equations thanks to data.,,
45
+ Its applications are ...,Data Science,Total Bootcamp,A,Limited to a small amount of fields and use cases.,Close to unlimited and find use cases in almost every known fields where data can be collected.,,,
46
+ What are the first things you want to do when you start a Data Science project ?,Data Science,Total Bootcamp,A C,Define the problem.,Choose the model you want to implement.,Obtain the data and check if it fits our standard.,Ask Paul what to do next.,
47
+ Are every datasets worth a Data Science project ?,Data Science,Total Bootcamp,A,No.,"If it's big enough, yes.",Yes.,,
48
+ "When the dataset is all set and obtained, what do you need to do ?",Data Science,Total Bootcamp,B C,Run a model on it and then do a series of statistical tests on it.,Explore it and do a series of statistical tests on it.,Pre-process it by cleaning it of missing values or irrelevant data.,,
49
+ What are the best tools you can use when starting a project?,Data Science,Total Bootcamp,A B C D ,Data Visualization.,Statistical tests.,Expert intuitions. ,Correlation matrix ,Gut feelings.
50
+ "When building a model, you have to",Data Science,Total Bootcamp,B,Look out for parameters that can be optimized and optimze them.,Train it on all the data available.,,,
51
+ "Your model is all done and working, what's next?",Data Science,Total Bootcamp,B,My project is done ! ,Analyze the results and tune the existing model to fit best the problem defined initially.,,,
52
+ What is Machine learning ?,Machine Learning,Total Bootcamp,B,The phenomenon in which an algorithm realizes it is not paid enough and puts itself on a strike.,An application of artificial intelligence that provides systems the ability to automatically learn and improve from experience without being explicitly programmed.,Exactly what Datascientest offers : a way to learn through machines.,When an algorithm is programmed to adapt itself to a given situation.,
53
+ Supervised learning ...,Machine Learning,Total Bootcamp,A C,Is when the data we use to fit the model on is labeled.,Is when the algorithm includes steps to check the progression of the computation process.,Allows to predict the value or the class of a new element.,"Allows data partitioning according to the features,distribution density estimation and dimension reduction.",
54
+ Unsupervised learning ...,Machine Learning,Total Bootcamp,A C ,Is when the data we feed to our model is not labeled.,Allows to predict the value or the class of a new element.,"Allows data partitioning according to the features,distribution density estimation and dimension reduction.",,
55
+ Classification,Machine Learning,Total Bootcamp,B,Is used when the target we aim to predict is continuous.,Is used when the target we aim to work on is discrete.,Is not a method needing artificial intelligence techniques.,,
56
+ Regression,Machine Learning,Total Bootcamp,A,Is used when the target we aim to predict is continuous.,Is used when the target we aim to predict is discrete.,Gives the same results with two points or a thousand.,,
57
+ Overfitting is,Machine Learning,Total Bootcamp,A,When the model fits too much the training data and don’t generalize enough.,When the model takes too much time to train on the data.,When the algorithm can't store anymore the results of the fitting process.,,
58
+ A way to handle imbalanced datasets is,Machine Learning,Total Bootcamp,"B,C",Filtering,Under sampling,Over sampling,,
59
+ Pourquoi utiliser des APIs?,Automation,Test de validation,D,Pour isoler les services de l'utilisateur final,Pour normaliser les communications entre services,Pour permettre une évolution facile des services,Tous ces points,
60
+ "En utilisant Flask, on permet à un utilisateur ou à une machine d'utiliser un service avec ",Automation,Test de validation,C,SQL,Python,HTTP,Java,
61
+ Pourquoi utiliser Docker?,Automation,Test de validation,D,Pour déployer facilement et rapidement des processus,Pour isoler des processus de la machine hôte,Pour tester des services rapidement,Tous ces points,
62
+ "Si on fait un parallèle avec la programmation orientée objet, les images de containers Docker sont l'équivalent des",Automation,Test de validation,A,Classes,Instances de classes,Méthodes,Objets,
63
+ "Pour faciliter le passage de fichiers entre la machine hôte et un container Docker, on peut utiliser les",Automation,Test de validation,C,Images,Networks,Volumes,Containers,
64
+ "Pour faciliter la communication entre la machine hôte et un container Docker, on peut utiliser les",Automation,Test de validation,B,Images,Networks,Volumes,Containers,
65
+ Quelle commande permet de lancer un container Docker ?,Automation,Test de validation,B,docker image run nom_de_l_image,docker container run nom_de_l_image,docker image pull nom_de_l_image,docker container pull nom_de_l_image,
66
+ A quoi sert Docker-Compose ?,Automation,Test de validation,A,A répertorier les images publiques de containers,A déployer plusieurs containers en même temps,A créer sa propre image Docker,Tous ces points,
67
+ A quoi sert Docker-Compose ?,Automation,Test de validation,B,A répertorier les images publiques de containers,A déployer plusieurs containers en même temps,A créer sa propre image Docker,Tous ces points,
68
+ "Dans Airflow, le DAG répertorie",Automation,Test de validation,D,Les tâches à effectuer,Les actions à prendre en cas d'échecs,L'enchaînement des tâches à effectuer,Tous ces points,
69
+ Quelle est la différence entre le processing time et le event time ?,Streaming de données,Test de validation,B,L’un correspond au temps de début de calcul alors que l’autre correspond à la durée nécessaire pour le calcul,L’un correspond à l’entrée de la donnée dans le système alors que l’autre correspond à la date de création de la donnée,Ce sont en fait la même chose,,
70
+ Kafka est un système de messagerie,Streaming de données,Test de validation,A,Publication/Abonnement + Asynchrone,Publication/Abonnement + Synchrone,Orienté queue + Asynchrone,Orienté queue+ Synchrone,
71
+ "Dans Kafka, les brokers permettent de",Streaming de données,Test de validation,,distribuer le stockage intermédiaire des données,répartir la charge du flux des données,prévenir les pannes du système,tous ces points,
72
+ "Dans Kafka, dans un consumer group, les consommateurs accédent",Streaming de données,Test de validation,,chacun à toutes les données disponibles,chacun à une partie des données relativement à sa capacité de consommation,"chacun à une partie des données, réparti de manière uniforme",,
73
+ Quelle est la différence entre Hadoop et Spark?,Streaming de données,Test de validation,,Hadoop est un système de calcul et de stockage alors que Spark n’est qu’un système de calcul,Spark est écrit en Scala alors que Hadoop est écrit en Java,Spark écrit les valeurs en mémoire alors que Hadoop les écrit sur disque,Tous ces points,
74
+ Quelle librairie de Spark n’existe pas ?,Streaming de données,Test de validation,,SparkSQL,SparkML,Spark Streaming,Spark IO,
75
+ Que signigie RDD ?,Streaming de données,Test de validation,,Raw distributed dataset,Redundant Distributed Dataset,Resilient Distributed DataSet,,
76
+ Qu’est-ce que le DAG ?,Streaming de données,Test de validation,,Une représentation des tâches à exécuter,Un dispositif qui permet d’optimiser les claculs,,,
77
+ Les Dstreams sont définis par,Streaming de données,Test de validation,,Une limite de temps,Une limite d’espace,Une limite déterminée aléatoirement,Tous ces points,
78
+ "Dans HBase, les données sont stockées par",Streaming de données,Test de validation,,Lignes,Familles de colonnes,Clefs,,
requirements.txt CHANGED
@@ -1,4 +1,21 @@
1
- uvicorn
2
- flask
3
- vaderSentiment
4
- flasgger
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ annotated-types==0.6.0
2
+ anyio==4.2.0
3
+ click==8.1.7
4
+ exceptiongroup==1.2.0
5
+ fastapi==0.109.2
6
+ h11==0.14.0
7
+ httptools==0.1.2
8
+ idna==3.6
9
+ numpy==1.24.4
10
+ pandas==1.5.3
11
+ pydantic==2.6.1
12
+ pydantic-core==2.16.2
13
+ python-dateutil==2.8.2
14
+ pytz==2024.1
15
+ requests==2.7.0
16
+ six==1.16.0
17
+ sniffio==1.3.0
18
+ starlette==0.36.3
19
+ typing-extensions==4.9.0
20
+ uvicorn==0.27.1
21
+ uvloop==0.19.0