Docfile commited on
Commit
a531cbc
1 Parent(s): 3ea01fd

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +98 -124
app.py CHANGED
@@ -1,12 +1,13 @@
1
- from flask import Flask, request, render_template, jsonify
2
- import PIL.Image
3
- import google.generativeai as genai
 
 
4
  import os
5
- from tempfile import NamedTemporaryFile
6
- import tempfile
7
- app = Flask(__name__)
8
 
9
- # Configuration de Gemini
10
  generation_config = {
11
  "temperature": 1,
12
  "max_output_tokens": 8192,
@@ -33,128 +34,101 @@ safety_settings = [
33
 
34
  GOOGLE_API_KEY = os.environ.get("TOKEN")
35
 
36
- genai.configure(api_key=GOOGLE_API_KEY)
37
-
38
- @app.route('/', methods=['GET'])
39
- def svt():
40
- """Renders the SVT page."""
41
- return render_template("svt.html")
42
-
43
-
44
- methodologie_svt = {
45
-
46
- "Restitution organisée des connaissances": """
47
- **Restitution organisée des connaissances (ROC)**
48
-
49
- **Objectif:** Exposer, dans un texte structuré, scientifiquement et grammaticalement correct, illustré si nécessaire, des connaissances sur un point du programme.
50
-
51
- **Structure de la ROC:**
52
-
53
- * **Introduction:**
54
- * Contexte: Synthèse des savoirs (prérequis) nécessaires pour aborder le thème.
55
- * Problème: Reformulation de la consigne sous forme interrogative, découlant logiquement du contexte.
56
- * Plan: Annonce des parties du développement.
57
- * **Développement:**
58
- * Au moins deux paragraphes séparés par une ligne, débutant par un titre souligné.
59
- * Titres: Reprise des parties annoncées dans le plan.
60
- * Contenu: Solution du problème, articulation logique des paragraphes.
61
- * Schéma: Si la consigne l'exige.
62
- * **Conclusion:**
63
- * Réponse logique au problème posé dans l'introduction.
64
- * Intégration des aspects développés.
65
- * Correspondance à la thématique de l'exercice.
66
-
67
- **Conseils:**
68
-
69
- * L'exercice ne comporte pas de documents.
70
- * Le sujet comporte un thème, un contexte et une consigne.
71
- * L'exercice est pondéré sur 7 à 8 points.
72
- """,
73
- "Exploitation du document": """
74
-
75
-
76
- **Exploitation de documents (ED)**
77
-
78
- **Objectif:** Trouver le lien entre les informations présentées par un des documents et les connaissances d'un segment de connaissances (partie du programme) en vue de la résolution d'un problème scientifique.
79
-
80
- **Structure de l'ED:**
81
-
82
- * **Introduction** (peut être écrite au brouillon) : Problème (reformulation de la consigne)
83
- * **Pour chaque document :**
84
- * **Présentation (CP1):** Type de document + objet d'étude (cf. titre).
85
- * **Analyse (CP2):** Description du fait expérimental (comparaison de courbes, résultats d'expérience) et/ou présentation du fait d'observation (changement de coloration, % de phénotypes).
86
- * **Information saisie (CP3):** Conclusion partielle, fait à interpréter.
87
- * **Mise en relation (CP4):** Interprétation de l'information saisie en utilisant les connaissances acquises, signification permettant la résolution du problème.
88
- * **Synthèse des mises en relation (CP5)** : Lien pertinent et cohérent entre toutes les significations (mise en relation) des informations utiles pour résoudre le problème (répondre à la consigne). Cette partie est séparée du reste par deux lignes.
89
-
90
- **Conseils:**
91
-
92
- * L'exercice comporte un thème, un contexte, une consigne, un ou deux documents, et une pondération (7-8 points).
93
- * Le contexte établit le lien entre le thème et les documents.
94
- * La consigne guide l'élève dans les différentes tâches.
95
- * Les documents doivent comporter un titre et une source, être pertinents, lisibles, et suivre l'ordre chronologique de la résolution.
96
- * Ne pas paraphraser, copier ou faire une description intégrale dans l'analyse (CP2).
97
- * La tâche 4 (CP4) est spécifique à cet exercice.
98
- * Mentionner le document traité (ex: Document 1).
99
-
100
-
101
- réponse attendu uniquement en langue française.
102
- """,
103
- "Synthèse": """
104
- **Élaboration d'une synthèse (ES)**
105
-
106
- **Objectif:** Dégager des informations pertinentes d'un ensemble de documents en vue de résoudre un problème scientifique. La résolution du problème ne fait pas appel directement aux connaissances du cours.
107
-
108
- **Structure de l'ES:**
109
-
110
- * **Introduction** (peut être écrite au brouillon) : Problème (reformulation de la consigne)
111
- * **Pour chaque document :**
112
- * **Présentation (CP1):** Type de document + objet d'étude (cf. titre).
113
- * **Analyse (CP2):** Description du fait expérimental (comparaison de courbes, résultats d'expérience) et/ou présentation du fait d'observation (changement de coloration, % de phénotypes).
114
- * **Conclusion partielle (CP3):** Synthèse de l'analyse, élément de réponse au problème.
115
- * **Conclusion générale (CP4):** Récapitulation des conclusions partielles, réponse à la consigne.
116
-
117
- **Conseils:**
118
-
119
- * L'exercice comporte un thème, un contexte, une consigne, deux ou trois documents, et une pondération (5 points).
120
- * Le contexte établit le lien entre le thème et les documents.
121
- * La consigne guide l'élève dans les différentes tâches.
122
- * Les documents doivent comporter un titre et une source, être pertinents, lisibles, et suivre l'ordre chronologique de la résolution.
123
- * Ne pas paraphraser, copier ou faire une description intégrale dans l'analyse (CP2).
124
- * La tâche 3 (CP3) est spécifique à cet exercice.
125
- * Mentionner le document traité (ex: Document 1).
126
- * Toutes les informations nécessaires sont dans les documents.
127
- """
128
- }
129
 
 
 
130
 
131
- @app.route('/svt_submit', methods=['POST'])
132
- def svt_submit():
133
- """Handles the submission of SVT exercises."""
134
- option = request.form.get('option')
135
- images = request.files.getlist('images')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
136
 
137
- content = [f"J'aimerais que tu traites entièrement cet exercice en respectant scrupuleusement la méthodologie d'SVT suivante :\n\n{methodologie_svt[option]}\n\nLe type d'exercice selon la méthodologie est : {option}. Voici les images de l'exercice:"]
138
- temp_files = []
 
 
139
 
 
 
140
  try:
141
- for image in images:
142
- if image:
143
- with tempfile.NamedTemporaryFile(delete=False, suffix=os.path.splitext(image.filename)[1]) as temp_file:
144
- image.save(temp_file.name)
145
- temp_files.append(temp_file.name)
146
- content.append(PIL.Image.open(temp_file.name))
147
-
148
- model = genai.GenerativeModel(model_name="models/gemini-2.0-flash-exp", safety_settings=safety_settings)
149
- response = model.generate_content(content, request_options={"timeout": 600})
 
 
 
 
 
 
 
 
 
 
 
150
 
151
- return jsonify({"response": response.text})
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
152
 
153
  except Exception as e:
154
- return jsonify({"error": str(e)}), 500
155
- finally:
156
- for temp_file in temp_files:
157
- try:
158
- os.unlink(temp_file)
159
- except Exception as e:
160
- print(f"Error deleting temporary file {temp_file}: {e}")
 
 
 
 
1
+ from flask import Flask, request, jsonify, send_file
2
+ from flask_cors import CORS
3
+ from PIL import Image, ImageDraw
4
+ import io
5
+ import json
6
  import os
7
+ import uuid
8
+ import google.generativeai as genai
9
+
10
 
 
11
  generation_config = {
12
  "temperature": 1,
13
  "max_output_tokens": 8192,
 
34
 
35
  GOOGLE_API_KEY = os.environ.get("TOKEN")
36
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
 
38
+ # Configuration de l'API Gemini
39
+ genai.configure(api_key=GOOGLE_API_KEY) # Remplacez par votre clé API
40
 
41
+ app = Flask(__name__)
42
+ CORS(app)
43
+
44
+ # Prompt pour la détection d'objets
45
+ DETECTION_PROMPT = "Detect items, with no more than 20 items. Output a json list where each entry contains the 2D bounding box in \"box_2d\" and a text label in \"label\"."
46
+
47
+ # Prompt pour la description d'image satellite militaire
48
+ DESCRIPTION_PROMPT = """
49
+ Décrivez en détail cette image satellite militaire. Soyez précis et exhaustif dans votre analyse.
50
+ Identifiez les éléments clés tels que :
51
+ - **Infrastructures** : Bâtiments, routes, ponts, aéroports, ports, etc.
52
+ - **Véhicules** : Chars, avions, navires, véhicules de transport de troupes, etc.
53
+ - **Unités militaires** : Formations de troupes, positions d'artillerie, camps, etc.
54
+ - **Défenses** : Bunkers, tranchées, barbelés, etc.
55
+ - **Éléments géographiques** : Relief, végétation, cours d'eau, etc.
56
+ - **Activités** : Mouvements de troupes, entraînements, constructions, etc.
57
+ - **Anomalies** : Tout ce qui semble inhabituel ou suspect.
58
+
59
+ Fournissez une évaluation globale de la situation et des implications stratégiques possibles.
60
+ """
61
 
62
+ # Dossier pour enregistrer temporairement les images
63
+ UPLOAD_FOLDER = 'uploads'
64
+ app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
65
+ os.makedirs(UPLOAD_FOLDER, exist_ok=True)
66
 
67
+ @app.route('/analyze', methods=['POST'])
68
+ def analyze_image():
69
  try:
70
+ if 'file' not in request.files:
71
+ return jsonify({'error': 'No file part'}), 400
72
+
73
+ file = request.files['file']
74
+ if file.filename == '':
75
+ return jsonify({'error': 'No selected file'}), 400
76
+
77
+ if file:
78
+ # Générer un nom de fichier unique pour éviter les conflits
79
+ unique_filename = str(uuid.uuid4()) + os.path.splitext(file.filename)[1]
80
+ filename = os.path.join(app.config['UPLOAD_FOLDER'], unique_filename)
81
+ file.save(filename)
82
+
83
+ # 1. Détection d'objets avec Gemini
84
+ model = genai.GenerativeModel("gemini-1.5-flash-exp",safety_settings=safety_settings,generation_config=generation_config)
85
+ image_part = {
86
+ "mime_type": "image/jpeg", # Assurez-vous que cela corresponde au type de votre image
87
+ "data": open(filename, "rb").read() # Le fichier est lu ici
88
+ }
89
+ response = model.generate_content([DETECTION_PROMPT, image_part])
90
 
91
+ try:
92
+ detection_results = json.loads(response.text)
93
+ except json.JSONDecodeError:
94
+ print(f"Erreur de décodage JSON : {response.text}")
95
+ return jsonify({'error': 'Erreur lors de la détection des objets (JSON invalide)'}), 500
96
+
97
+ # 2. Dessiner les boîtes englobantes
98
+ image = Image.open(filename)
99
+ draw = ImageDraw.Draw(image)
100
+
101
+ for item in detection_results:
102
+ box = item['box_2d']
103
+ label = item['label']
104
+ draw.rectangle(box, outline=(255, 0, 0), width=2)
105
+ text_position = (box[0], box[1] - 10)
106
+ draw.text(text_position, label, fill=(255, 255, 255))
107
+
108
+ # Enregistrer l'image avec les boîtes
109
+ output_filename = os.path.join(app.config['UPLOAD_FOLDER'], 'output_' + unique_filename)
110
+ image.save(output_filename)
111
+
112
+ # 3. Générer la description
113
+
114
+ response = model.generate_content([DESCRIPTION_PROMPT, image_part])
115
+ description = response.text
116
+
117
+ # 4. Renvoyer les résultats
118
+ return jsonify({
119
+ 'image_path': '/uploads/' + 'output_' + unique_filename, # Chemin relatif vers l'image
120
+ 'description': description,
121
+ 'detected_objects': detection_results
122
+ })
123
 
124
  except Exception as e:
125
+ print(f"Une erreur s'est produite : {e}")
126
+ return jsonify({'error': f'Erreur lors du traitement de l\'image : {e}'}), 500
127
+
128
+ # Servir les fichiers statiques depuis le dossier 'uploads'
129
+ @app.route('/uploads/<filename>')
130
+ def uploaded_file(filename):
131
+ return send_file(os.path.join(app.config['UPLOAD_FOLDER'], filename))
132
+
133
+ if __name__ == '__main__':
134
+ app.run(debug=True)