Skip to content

Commit

Permalink
Merge branch 'develop' into enh/migrate-components-vue2-to-vue3
Browse files Browse the repository at this point in the history
  • Loading branch information
NadeigeC authored Mar 30, 2023
2 parents 1ca2394 + adf8c60 commit e8d33f1
Show file tree
Hide file tree
Showing 21 changed files with 380 additions and 618 deletions.
180 changes: 91 additions & 89 deletions backend/src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,64 @@ def get_device(user_agent) -> str:
return "other"


def get_base_logs(user_agent, user_id) -> dict:
extras_logging = {
"bg_date": datetime.now().isoformat(),
"bg_user_id": user_id,
"bg_version": APP_VERSION,
"bg_model": MODEL_VERSION,
"bg_device": get_device(user_agent),
"bg_device_family": user_agent.device.family,
"bg_device_os": user_agent.os.family,
"bg_device_browser": user_agent.browser.family,
}
return extras_logging


def upload_image_ovh(content: bytes, img_name: str):
""" Uploads an image to owh swift container basegun-public
path uploaded-images/WORKSPACE/img_name
where WORKSPACE is dev, preprod or prod
Args:
content (bytes): file content
img_name (str): name we want to give on ovh
"""
num_tries = 0
LIMIT_TRIES = 5
image_path = os.path.join(CLOUD_PATH, img_name)
start = time.time()

if not conn:
logger.exception("Variables not set for using OVH swift.", extra={
"bg_error_type": "NameError"
})
return

while num_tries <= LIMIT_TRIES:
num_tries += 1
extras_logging = {
"bg_date": datetime.now().isoformat(),
"bg_upload_time": time.time()-start,
"bg_image_url": image_path
}
try:
conn.put_object("basegun-public",
f'uploaded-images/{os.environ["WORKSPACE"]}/{img_name}',
contents=content)
# if success, get out of the loop
logger.info("Upload to OVH successful", extra=extras_logging)
break
except Exception as e:
if (num_tries <= LIMIT_TRIES and e.__class__.__name__ == "ClientException"):
# we try uploading another time
time.sleep(30)
continue
else:
extras_logging["bg_error_type"] = e.__class__.__name__
logger.exception(e, extra=extras_logging)


####################
# SETUP #
####################
Expand Down Expand Up @@ -151,50 +209,6 @@ def get_device(user_agent) -> str:
logger.warn('Variables necessary for OVH connection not set !')


def upload_image_ovh(content: bytes, img_name: str):
""" Uploads an image to owh swift container basegun-public
path uploaded-images/WORKSPACE/img_name
where WORKSPACE is dev, preprod or prod
Args:
content (bytes): file content
img_name (str): name we want to give on ovh
"""
num_tries = 0
LIMIT_TRIES = 5
image_path = os.path.join(CLOUD_PATH, img_name)
start = time.time()

if not conn:
logger.exception("Variables not set for using OVH swift.", extra={
"bg_error_type": "NameError"
})
return

while num_tries <= LIMIT_TRIES:
num_tries += 1
extras_logging = {
"bg_date": datetime.now().isoformat(),
"bg_upload_time": time.time()-start,
"bg_image_url": image_path
}
try:
conn.put_object("basegun-public",
f'uploaded-images/{os.environ["WORKSPACE"]}/{img_name}',
contents=content)
# if success, get out of the loop
logger.info("Upload to OVH successful", extra=extras_logging)
break
except Exception as e:
if (num_tries <= LIMIT_TRIES and e.__class__.__name__ == "ClientException"):
# we try uploading another time
time.sleep(30)
continue
else:
extras_logging["bg_error_type"] = e.__class__.__name__
logger.exception(e, extra=extras_logging)


####################
# ROUTES #
####################
Expand Down Expand Up @@ -232,17 +246,9 @@ async def imageupload(

# prepare content logs
user_agent = parse(request.headers.get("user-agent"))
extras_logging = {
"bg_date": datetime.now().isoformat(),
"bg_upload_time": round(time.time()-date, 2),
"bg_geolocation": geolocation,
"bg_device": get_device(user_agent),
"bg_device_family": user_agent.device.family,
"bg_device_os": user_agent.os.family,
"bg_device_browser": user_agent.browser.family,
"bg_version": APP_VERSION,
"bg_model": MODEL_VERSION,
}
extras_logging = get_base_logs(user_agent, user_id)
extras_logging["bg_geolocation"] = geolocation
extras_logging["bg_upload_time"] = round(time.time() - date, 2)

try:
img_name = str(uuid4()) + os.path.splitext(image.filename)[1]
Expand All @@ -257,7 +263,7 @@ async def imageupload(
if not user_id:
user_id = uuid4()
response.set_cookie(key="user_id", value=user_id)
extras_logging["bg_user_id"] = user_id
extras_logging["bg_user_id"] = user_id

# send image to model for prediction
start = time.time()
Expand Down Expand Up @@ -287,51 +293,47 @@ async def imageupload(
raise HTTPException(status_code=500, detail=str(e))


@app.post("/feedback")
@app.post("/identification-feedback")
async def log_feedback(request: Request, user_id: Union[str, None] = Cookie(None)):
res = await request.json()

user_agent = parse(request.headers.get("user-agent"))
extras_logging = get_base_logs(user_agent, user_id)

extras_logging["bg_feedback_bool"] = res["feedback"]
for key in ["image_url", "label", "confidence", "confidence_level"]:
extras_logging["bg_"+key] = res[key]

extras_logging = {
"bg_date": datetime.now().isoformat(),
"bg_image_url": res["image_url"],
"bg_feedback_bool": res["feedback"],
"bg_label": res["label"],
"bg_confidence": res["confidence"],
"bg_confidence_level": res["confidence_level"],
"bg_user_id": user_id,
"bg_device": get_device(user_agent),
"bg_device_family": user_agent.device.family,
"bg_device_os": user_agent.os.family,
"bg_device_browser": user_agent.browser.family,
"bg_version": APP_VERSION,
}
logger.info("Identification feedback", extra=extras_logging)
return


@app.post("/tutorial-feedback")
async def log_tutorial_feedback(request: Request, user_id: Union[str, None] = Cookie(None)):
res = await request.json()

user_agent = parse(request.headers.get("user-agent"))
extras_logging = get_base_logs(user_agent, user_id)

for key in ["image_url", "label", "confidence", "confidence_level",
"tutorial_feedback", "tutorial_option", "route_name"]:
extras_logging["bg_"+key] = res[key]

extras_logging = {
"bg_date": datetime.now().isoformat(),
"bg_image_url": res["image_url"],
"bg_tutorial_feedback": res["tutorial_feedback"],
"bg_label": res["label"],
"bg_confidence": res["confidence"],
"bg_confidence_level": res["confidence_level"],
"bg_route_name": res["route_name"],
"bg_current_step": res["current_step"],
"bg_tutorial_option": res["tutorial_option"],
"bg_tutorial_ammo": res["tutorial_ammo"],
"bg_user_id": user_id,
"bg_device": get_device(user_agent),
"bg_device_family": user_agent.device.family,
"bg_device_os": user_agent.os.family,
"bg_device_browser": user_agent.browser.family,
"bg_version": APP_VERSION,
}
logger.info("Tutorial feedback", extra=extras_logging)
return


@app.post("/identification-dummy")
async def log_identification_dummy(request: Request, user_id: Union[str, None] = Cookie(None)):
res = await request.json()

user_agent = parse(request.headers.get("user-agent"))
extras_logging = get_base_logs(user_agent, user_id)

# to know if the firearm is dummy or real
extras_logging["bg_dummy_bool"] = res["is_factice"]
for key in ["image_url", "label", "confidence", "confidence_level", "tutorial_option"]:
extras_logging["bg_"+key] = res[key]

logger.info("Identification dummy", extra=extras_logging)
return
41 changes: 21 additions & 20 deletions backend/tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import requests
from PIL import Image, ImageChops


class TestModel(unittest.TestCase):
def __init__(self, *args, **kwargs):
super(TestModel, self).__init__(*args, **kwargs)
Expand All @@ -21,6 +22,15 @@ def test_version(self):
self.assertNotEqual(r.text, "-1")
self.assertEqual(len(r.text.split('.')), 2) # checks version has format X.Y

def check_log_base(self, log):
self.assertTrue(
{'timestamp', 'version', 'host', 'level', 'short_message', '_bg_date', '_bg_user_id',
'_bg_device', '_bg_device_os', '_bg_device_family', '_bg_device_browser', '_bg_version',
'_bg_model'}.issubset(set(log.keys()))
)
self.assertEqual(log["level"], 6)
self.assertTrue(log["_bg_model"].startswith("EffB"))

def test_upload_and_logs(self):
"""Checks that the file upload works properly"""
path = os.path.join(
Expand All @@ -37,13 +47,12 @@ def test_upload_and_logs(self):
res = r.json()

# checks that the json result is as expected
self.assertEqual(set(res.keys()), set({"label", "confidence", "confidence_level", "path"}))
self.assertEqual(res["label"], "revolver")
self.assertAlmostEqual(res["confidence"], 99.53, places=1)
self.assertTrue(res["confidence_level"], "high")
self.assertTrue("ovh" in res["path"])
# checks that written file is exactly the same as input file
time.sleep(30)
time.sleep(10)
response = requests.get(res["path"])
with Image.open(path) as image_one:
with Image.open(BytesIO(response.content)) as image_two:
Expand All @@ -58,39 +67,31 @@ def test_upload_and_logs(self):
self.assertEqual(r.json()[0]["short_message"], "Upload to OVH successful")
# checks the previous log "Identification request"
log = r.json()[1]
self.assertEqual(
set(log.keys()),
set({'timestamp', '_bg_device', 'host', '_bg_model_time', 'version', '_bg_device_os', '_bg_device_family',
'short_message', '_bg_confidence', '_bg_confidence_level', '_bg_upload_time', '_bg_date', '_bg_user_id', '_bg_label', '_bg_image_url',
'level', '_bg_geolocation', '_bg_device_browser', '_bg_version', '_bg_model'})
)
self.assertEqual(log["level"], 6)
self.check_log_base(log)
self.assertEqual(log["short_message"], "Identification request")
self.assertTrue("-" in log["_bg_user_id"])
self.assertEqual(log["_bg_geolocation"], geoloc)
self.assertEqual(log["_bg_label"], "revolver")
self.assertAlmostEqual(log["_bg_confidence"], 99.53, places=1)
self.assertTrue(log["_bg_upload_time"]>=0)

def test_feedback_and_logs(self):
"""Checks that the feedback works properly"""
confidence = 90
label = "revolver"
confidence_level = "high"
r = requests.post(self.url + "/feedback",
json={"image_url": "test", "feedback": False, "confidence": confidence, "label": label, "confidence_level": confidence_level})
image_url = "https://storage.gra.cloud.ovh.net/v1/test"
r = requests.post(self.url + "/identification-feedback",
json={"image_url": image_url, "feedback": True, "confidence": confidence, "label": label, "confidence_level": confidence_level})

self.assertEqual(r.status_code, 200)
r = requests.get(self.url + "/logs")
self.assertEqual(r.status_code, 200)
log = r.json()[0]
self.assertEqual(
set(log.keys()),
set({'timestamp', '_bg_device', 'host', '_bg_feedback_bool', 'version', '_bg_device_os', '_bg_device_family',
'short_message', '_bg_confidence', '_bg_confidence_level', '_bg_date', '_bg_user_id', '_bg_label', '_bg_image_url',
'level', '_bg_device_browser', '_bg_version'})
)
self.assertEqual(log["level"], 6)
self.check_log_base(log)
self.assertEqual(log["short_message"], "Identification feedback")
self.assertEqual(log["_bg_image_url"], "test")
self.assertFalse(log["_bg_feedback_bool"])
self.assertEqual(log["_bg_image_url"], image_url)
self.assertTrue(log["_bg_feedback_bool"])
self.assertEqual(log["_bg_confidence"], confidence)
self.assertEqual(log["_bg_label"], label)
self.assertEqual(log["_bg_confidence_level"], confidence_level)
Expand Down
2 changes: 2 additions & 0 deletions docker-compose-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ services:
- OS_PROJECT_NAME
- http_proxy
- https_proxy
- no_proxy
- WORKSPACE=dev
- REQUESTS_CA_BUNDLE=$CACERT_LOCATION
image: basegun-backend:${TAG}-dev
ports:
- 5000:5000
Expand Down
26 changes: 0 additions & 26 deletions frontend/src/App.vue
Original file line number Diff line number Diff line change
@@ -1,49 +1,23 @@
<script setup>
import { registerSW } from 'virtual:pwa-register'
// import { ref } from 'vue'
import { useAppStore } from './stores/app.js'
import HeaderMain from './components/HeaderMain.vue'
// const needRefresh = ref(false)
const appStore = useAppStore()
registerSW({ immediate: true })
// const updateSW = registerSW({
// immediate: true,
// onNeedRefresh () {
// needRefresh.value = true
// },
// onOfflineReady () {},
// })
</script>

<template>
<HeaderMain v-show="appStore.displayHeader" />
<!-- <DsfrCallout
v-show="needRefresh"
class="col-lg-6 mx-auto refresh"
content=""
title="Une mise à jour est disponible"
>
<DsfrButton
secondary
@click="updateSW()"
>
Mettre à jour
</DsfrButton>
</DsfrCallout> -->
<router-view />
</template>

<style scoped>
#app {
/* font-family: Avenir, Helvetica, Arial, sans-serif; */
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
/* text-align: center; */
color: #2c3e50;
}
Expand Down
Loading

0 comments on commit e8d33f1

Please sign in to comment.