Traitement des erreurs API (templates rudimentaires)
This commit is contained in:
parent
42570cf435
commit
d733e68683
@ -35,7 +35,9 @@ Côté ScoDoc, créer un rôle et un utilisateur dédiés:
|
||||
flask create-role AutoSco
|
||||
flask edit-role AutoSco -a ScoView
|
||||
flask user-create autosco AutoSco @all
|
||||
flask user-edit autosco --allow-scodoc-login
|
||||
flask user-password autosco
|
||||
|
||||
```
|
||||
|
||||
Configurer les paramètres d'accès dans AutoSco: éditer le fichier
|
||||
|
@ -1,6 +1,10 @@
|
||||
from flask import current_app, g, request
|
||||
import sys
|
||||
import time
|
||||
|
||||
from flask import current_app, g, render_template, request
|
||||
from flask import Flask
|
||||
|
||||
from scodoc.api import APIError, ScoDocAuthError
|
||||
from config import DevConfig
|
||||
|
||||
|
||||
@ -18,6 +22,30 @@ class ReverseProxied:
|
||||
environ["wsgi.url_scheme"] = scheme # ou forcer à https ici ?
|
||||
return self.app(environ, start_response)
|
||||
|
||||
# --------- Logging
|
||||
def log(msg: str):
|
||||
"""log a message.
|
||||
If Flask app, use configured logger, else stderr.
|
||||
"""
|
||||
if current_app and not current_app.config["DEBUG"]:
|
||||
current_app.logger.info(msg)
|
||||
else:
|
||||
sys.stdout.flush()
|
||||
sys.stderr.write(
|
||||
f"""[{time.strftime("%a %b %d %H:%M:%S %Y")}] scodoc: {msg}\n"""
|
||||
)
|
||||
sys.stderr.flush()
|
||||
|
||||
def handle_sco_api_error(exc):
|
||||
"page d'erreur avec message"
|
||||
log("Error: handle_sco_api_error")
|
||||
return render_template("errors/sco_api_error.j2", exc=exc), 404
|
||||
|
||||
def handle_sco_auth_error(exc):
|
||||
"page d'erreur avec message"
|
||||
log("Error: handle_sco_auth_error")
|
||||
return render_template("errors/sco_auth_error.j2", exc=exc), 404
|
||||
|
||||
|
||||
def create_app(config_class=DevConfig):
|
||||
app = Flask(__name__, static_url_path="/AutoSco/static", static_folder="static")
|
||||
@ -27,4 +55,8 @@ def create_app(config_class=DevConfig):
|
||||
from app.views import bp
|
||||
|
||||
app.register_blueprint(bp)
|
||||
|
||||
app.register_error_handler(APIError, handle_sco_api_error)
|
||||
app.register_error_handler(ScoDocAuthError, handle_sco_auth_error)
|
||||
|
||||
return app
|
||||
|
13
app/templates/errors/sco_api_error.j2
Normal file
13
app/templates/errors/sco_api_error.j2
Normal file
@ -0,0 +1,13 @@
|
||||
{% extends 'base.j2' %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div>
|
||||
<h1>Erreur API</h1>
|
||||
<div>ScoDoc a renvoyé une erreur {{exc.status_code}}</div>
|
||||
<div>Message: {{exc.payload["message"]}}</div>
|
||||
<div>Requête: {{exc.message}}</div>
|
||||
<div>Si le problème persiste, veuillez contacter le support technique.</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
11
app/templates/errors/sco_auth_error.j2
Normal file
11
app/templates/errors/sco_auth_error.j2
Normal file
@ -0,0 +1,11 @@
|
||||
{% extends 'base.j2' %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div>
|
||||
<h1>Erreur d'authentification</h1>
|
||||
<div>AutoSco ne parvient pas à se connecter à ScoDoc</div>
|
||||
<div>Si le problème persiste, veuillez contacter le support technique.</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
@ -45,7 +45,6 @@ def make_shell_context():
|
||||
"scu": scu,
|
||||
}
|
||||
|
||||
# Start using:
|
||||
# flask run -p 5001 --host 0.0.0.0 --debug
|
||||
|
||||
if __name__ == "__main__":
|
||||
port = os.environ.get("PORT", 5001)
|
||||
app.run(debug=True, port=port)
|
||||
|
@ -40,7 +40,7 @@ class Config:
|
||||
SCODOC_CHECK_CERTIFICATE = os.environ.get("SCODOC_CHECK_CERTIFICATE", True)
|
||||
API_TIMEOUT = 120 # 2 minutes
|
||||
API_URL = SCODOC_URL + "/ScoDoc/api"
|
||||
SCODOC_DEPT_ACRONYM = "ESPL"
|
||||
SCODOC_DEPT_ACRONYM = os.environ.get("SCODOC_DEPT_ACRONYM", "ESPL")
|
||||
|
||||
def __getitem__(self, k) -> str | int | None:
|
||||
return getattr(self, k)
|
||||
|
@ -7,20 +7,8 @@ from flask import current_app
|
||||
import config
|
||||
|
||||
|
||||
def get_auth_headers(user: str, password: str, conf: config.Config) -> dict:
|
||||
"Demande de jeton, dict à utiliser dans les en-têtes de requêtes http"
|
||||
ans = requests.post(
|
||||
conf["API_URL"] + "/tokens",
|
||||
auth=(user, password),
|
||||
timeout=conf["API_TIMEOUT"],
|
||||
)
|
||||
if ans.status_code != 200:
|
||||
raise APIError(f"Echec demande jeton par {user}", status_code=ans.status_code)
|
||||
token = ans.json()["token"]
|
||||
return {"Authorization": f"Bearer {token}"}
|
||||
|
||||
|
||||
class APIError(Exception):
|
||||
"Error using ScoDoc API"
|
||||
def __init__(self, message: str = "", payload=None, status_code=None):
|
||||
self.message = message
|
||||
self.payload = payload or {}
|
||||
@ -29,6 +17,20 @@ class APIError(Exception):
|
||||
def __str__(self):
|
||||
return f"APIError: {self.message} payload={self.payload} status_code={self.status_code}"
|
||||
|
||||
class ScoDocAuthError(APIError):
|
||||
"Error getting ScoDoc token"
|
||||
|
||||
def get_auth_headers(user: str, password: str, conf: config.Config) -> dict:
|
||||
"Demande de jeton, dict à utiliser dans les en-têtes de requêtes http"
|
||||
ans = requests.post(
|
||||
conf["API_URL"] + "/tokens",
|
||||
auth=(user, password),
|
||||
timeout=conf["API_TIMEOUT"],
|
||||
)
|
||||
if ans.status_code != 200:
|
||||
raise ScoDocAuthError(f"Echec demande jeton par {user}", status_code=ans.status_code)
|
||||
token = ans.json()["token"]
|
||||
return {"Authorization": f"Bearer {token}"}
|
||||
|
||||
class APIAccessor:
|
||||
"Gestion bas niveau des accès à l'API ScoDoc"
|
||||
@ -64,9 +66,9 @@ class APIAccessor:
|
||||
print("url", url)
|
||||
print("reply", reply.text)
|
||||
try:
|
||||
payload = r.json()
|
||||
payload = reply.json()
|
||||
except requests.exceptions.JSONDecodeError:
|
||||
payload = r.text
|
||||
payload = reply.text
|
||||
raise APIError(
|
||||
errmsg or f"""erreur get {url} !""",
|
||||
payload,
|
||||
|
Loading…
x
Reference in New Issue
Block a user