API Flask Organiser ses class dans des fichiers
Résolu
valenrom97
-
valenrom97 -
valenrom97 -
Bonsoir, cela fait quelques temps que je m'intéresse aux applications pour mobile, applications Android en particulier. A plusieurs reprises j'ai tenté d'en réaliser. Voila, je compte me relancer dans la programmation d'une application. Je me suis donc renseigné sur ces histoires d'APIs. Jusqu'à présent je me faisais mes fonctions PHP un peu sales je pense… J'avais donc une API faite maison en PHP. Étant persuadé que ce n'est la bonne manière de procéder j'ai regardé sur internet les alternatives. J'ai trouvé FLASK (Restful) qui permet de mettre au point des APIs en python. Jusqu'à présent j'ai le code suivant:
Je souhaite maintenant ajouter d'autres class, comme une class "message" par exemple, cependant je souhaite séparer ces class dans des fichiers respectifs afin de conserver un code propre. Mais ce n'est pas évident… En PHP je peux faire des "includes" ou des "require_once" afin d'inclure du code "brute". Dans le cas présent, je souhaiterais dégager tout le code qui se trouve entre les deux commentaires "=== Import [start] ===" et "=== Import [end] ===" bref la class User().
Ainsi j'aurais une structure comme suit:
API/
==> main.py
==> Class/
==> Class/class_user.py
==> Class/class_msg.py
==> Class/class_auth.py
==> Class/class_etc.py
Voilà c'est un exemple, cela me paraît simple de procéder ainsi mais je n'y parvient pas pour autant, c'est pourquoi je me tourne vers vous :)
J'ai essayé avec des "import" mais je me retrouve avec des variables non déclarées, je m'y perds ! En théorie je pourrais mettre toutes les class dans le même fichier mais je suis persuadé que c'est une mauvaise pratique.
Si vous avez d'autres idées je suis preneur, par exemple, que pensez-vous de ces fameuses "sql stored procedure" que j'utilise dans mon code ? Certains utilisent "sql sqlalchemy" connaissez-vous la différence avec la méthode de connexion que j'utilise ? Avez-vous une idée sur le sujet ?
Merci beaucoup d'avoir pris le temps de lire ma question jusqu'au bout, et merci d'avance pour vos réponses :)
from flask import Flask from flaskext.mysql import MySQL from flask import jsonify from flask_restful import Api, Resource, reqparse app = Flask(__name__) api = Api(app) mysql = MySQL() # MySQL configurations app.config['MYSQL_DATABASE_USER'] = "dbuser" app.config['MYSQL_DATABASE_PASSWORD'] = "dbpass" app.config['MYSQL_DATABASE_DB'] = "app_myapp" app.config['MYSQL_DATABASE_HOST'] = "localhost" mysql.init_app(app) # ==================== Import [start] ==================== class User(Resource): def get(self, name): conn = mysql.connect() cursor =conn.cursor() parser = reqparse.RequestParser() parser.add_argument("key") args = parser.parse_args() if(args["key"] is None): return "No API Key provided", 403 cursor.callproc('check_api_key',([args["key"]])) data = cursor.fetchall() if(cursor.rowcount < 1): return "Forbidden, bad API Key", 403 cursor.callproc('get_user_infos',([name])) data = cursor.fetchall() if(cursor.rowcount < 1): return "User not found", 404 return jsonify(data) def post(self, name): parser = reqparse.RequestParser() parser.add_argument("age") parser.add_argument("occupation") args = parser.parse_args() for user in users: if(name == user["name"]): return "User with name {} already exists".format(name), 400 user = { "name": name, "age": args["age"], "occupation": args["occupation"] } users.append(user) return user, 201 def put(self, name): parser = reqparse.RequestParser() parser.add_argument("age") parser.add_argument("occupation") args = parser.parse_args() for user in users: if(name == user["name"]): user["age"] = args["age"] user["occupation"] = args["occupation"] return user, 200 user = { "name": name, "age": args["age"], "occupation": args["occupation"] } users.append(user) return user, 201 def delete(self, name): global users users = [user for user in users if user["name"] != name] return "{} is deleted.".format(name), 200 # ==================== Import [end] ==================== api.add_resource(User, "/user/<string:name>") #app.run(debug=True) app.run(host='0.0.0.0')
Je souhaite maintenant ajouter d'autres class, comme une class "message" par exemple, cependant je souhaite séparer ces class dans des fichiers respectifs afin de conserver un code propre. Mais ce n'est pas évident… En PHP je peux faire des "includes" ou des "require_once" afin d'inclure du code "brute". Dans le cas présent, je souhaiterais dégager tout le code qui se trouve entre les deux commentaires "=== Import [start] ===" et "=== Import [end] ===" bref la class User().
Ainsi j'aurais une structure comme suit:
API/
==> main.py
==> Class/
==> Class/class_user.py
==> Class/class_msg.py
==> Class/class_auth.py
==> Class/class_etc.py
Voilà c'est un exemple, cela me paraît simple de procéder ainsi mais je n'y parvient pas pour autant, c'est pourquoi je me tourne vers vous :)
J'ai essayé avec des "import" mais je me retrouve avec des variables non déclarées, je m'y perds ! En théorie je pourrais mettre toutes les class dans le même fichier mais je suis persuadé que c'est une mauvaise pratique.
Si vous avez d'autres idées je suis preneur, par exemple, que pensez-vous de ces fameuses "sql stored procedure" que j'utilise dans mon code ? Certains utilisent "sql sqlalchemy" connaissez-vous la différence avec la méthode de connexion que j'utilise ? Avez-vous une idée sur le sujet ?
Merci beaucoup d'avoir pris le temps de lire ma question jusqu'au bout, et merci d'avance pour vos réponses :)
A voir également:
- API Flask Organiser ses class dans des fichiers
- Renommer des fichiers en masse - Guide
- Fichiers epub - Guide
- Wetransfer gratuit fichiers lourd - Guide
- Explorateur de fichiers - Guide
- Gestion des fichiers - Télécharger - Gestion de fichiers
1 réponse
Pour ceux qui tomberaient sur le même os, j'ai trouvé une solution qui semble bien fonctionner. Voici la structure de mes fichiers:
myapp1/
myapp1/app.py
myapp1/__init__.py
myapp1/resources/
myapp1/resources/cars.py
myapp1/resources/msgs.py
myapp1/resources/users.py
myapp1/resources/db.py
myapp1/resources/__init__.py
Le dossier 'myapp1/resources/' contient mes différents fichiers représentant chacun une class particulière.
Je place également des fichiers '__init__.py' dans chaque dossier, je n'ai pas bien compris le fonctionnement de ces fichiers '__init__.py' mais il semblerait que cela permette à Python de traiter mes dossiers comme des Packages. Pour le moment ces fichiers sont vides, le simple fait qu'ils existent semble permettre cette histoire de Packages (à vérifier).
On a donc 3 class:
-cars
-users
-msgs
Le fichier db.py est un fichier de configuration pour communiquer avec la base de données. Il est inclus dans les class qui utilisent la BDD ainsi que dans le fichier principal 'myapp1/app.py '
Contenu de myapp1/app.py :
Contenu de myapp1/resources/cars.py :
Contenu de myapp1/resources/db.py :
Voilà tout, ce n'est peut-être pas la bonne méthode, sur ma route j'ai également croisé des réponses sur des forums qui préconisaient d'utiliser des " blueprints".
Afin d'ajouter des nouvelles class, il suffit de créer un nouveau fichier dans 'myapp1/resources/' puis de l'importer dans 'myapp1/app.py'. Enfin, il faut ajouter une ligne indiquant comment appeler la ressource depuis l'URL.
myapp1/
myapp1/app.py
myapp1/__init__.py
myapp1/resources/
myapp1/resources/cars.py
myapp1/resources/msgs.py
myapp1/resources/users.py
myapp1/resources/db.py
myapp1/resources/__init__.py
Le dossier 'myapp1/resources/' contient mes différents fichiers représentant chacun une class particulière.
Je place également des fichiers '__init__.py' dans chaque dossier, je n'ai pas bien compris le fonctionnement de ces fichiers '__init__.py' mais il semblerait que cela permette à Python de traiter mes dossiers comme des Packages. Pour le moment ces fichiers sont vides, le simple fait qu'ils existent semble permettre cette histoire de Packages (à vérifier).
On a donc 3 class:
-cars
-users
-msgs
Le fichier db.py est un fichier de configuration pour communiquer avec la base de données. Il est inclus dans les class qui utilisent la BDD ainsi que dans le fichier principal 'myapp1/app.py '
Contenu de myapp1/app.py :
from flask import Flask from flask.ext.mysql import MySQL from flask import jsonify from flask_restful import Api, Resource, reqparse from resources.users import User from resources.msgs import Msg from resources.cars import Car from resources.db import app, api api.add_resource(User, "/user/<string:name>") api.add_resource(Msg, "/msg/<string:name>") api.add_resource(Car, "/car/<string:name>") #app.run(debug=True) app.run(host='0.0.0.0')
Contenu de myapp1/resources/cars.py :
from flask_restful import Resource from resources.db import mysql class Car(Resource): def get(self, name): conn = mysql.connect() cursor =conn.cursor() cursor.callproc('get_car_from_id',(name)) data = cursor.fetchall() if(cursor.rowcount < 1): return "no lines... oups.. rien trouve :(" return data
Contenu de myapp1/resources/db.py :
from flask import Flask from flask.ext.mysql import MySQL from flask_restful import Api, Resource, reqparse app = Flask(__name__) api = Api(app) mysql = MySQL() # MySQL configurations app.config['MYSQL_DATABASE_USER'] = "dbuser" app.config['MYSQL_DATABASE_PASSWORD'] = "dbpass" app.config['MYSQL_DATABASE_DB'] = "app_myapp" app.config['MYSQL_DATABASE_HOST'] = "localhost" mysql.init_app(app)
Voilà tout, ce n'est peut-être pas la bonne méthode, sur ma route j'ai également croisé des réponses sur des forums qui préconisaient d'utiliser des " blueprints".
Afin d'ajouter des nouvelles class, il suffit de créer un nouveau fichier dans 'myapp1/resources/' puis de l'importer dans 'myapp1/app.py'. Enfin, il faut ajouter une ligne indiquant comment appeler la ressource depuis l'URL.
api.add_resource(...)