diff --git a/Makefile b/Makefile index af85ead4..6d42c1cc 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ SHELL := /bin/bash DOCKER := $(shell type -p docker) DC := $(shell type -p docker-compose) -TAG := 3.0 +TAG := 3.1 APP_NAME := basegun REG := ghcr.io ORG := datalab-mi diff --git a/backend/Dockerfile b/backend/Dockerfile index 581bd293..07b58d52 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -13,17 +13,15 @@ RUN apt update && apt install -y \ gcc \ && rm -rf /var/lib/apt/lists/* -# install python libraries -COPY requirements.txt ./ +# install python libraries (except torch) +COPY requirements/ requirements/ ENV PIP_CERT=$CACERT_LOCATION -RUN pip install --upgrade pip \ - && pip --default-timeout=300 install --no-cache-dir -f \ - https://download.pytorch.org/whl/cpu/torch_stable.html -r requirements.txt \ +RUN pip --default-timeout=300 install --upgrade pip \ + && pip --default-timeout=300 install --no-cache-dir -r requirements/common.txt \ && rm -r /root/.cache -# launch website ARG VERSION -ARG MODEL="EffB4_2022-03-02_08" +ARG MODEL="EffB7_2023-03-06_08" ENV SSL_CERT_FILE=$CACERT_LOCATION RUN curl -o model.pth https://storage.gra.cloud.ovh.net/v1/AUTH_df731a99a3264215b973b3dee70a57af/basegun-public/models/${MODEL}/${MODEL}.pth COPY src/ src/ @@ -31,13 +29,16 @@ RUN mkdir -p src/weights \ && mv model.pth src/weights/model.pth \ && echo '{"app": "'${VERSION}'", "model": "'${MODEL}'"}' > versions.json +# launch website FROM base as dev +RUN pip --default-timeout=300 install --no-cache-dir -r requirements/dev.txt CMD ["uvicorn", "src.main:app", "--reload", "--host", "0.0.0.0", "--port", "5000"] FROM base as test -RUN pip install requests && rm -r /root/.cache +RUN pip install -r requirements/dev.txt && pip install requests && rm -r /root/.cache COPY tests/ tests/ CMD ["uvicorn", "src.main:app", "--host", "0.0.0.0", "--port", "5000"] FROM base as prod +RUN pip install --no-cache-dir -r requirements/prod.txt CMD ["uvicorn", "src.main:app", "--host", "0.0.0.0", "--port", "5000"] diff --git a/backend/requirements.txt b/backend/requirements/common.txt similarity index 80% rename from backend/requirements.txt rename to backend/requirements/common.txt index ba804f3f..35ee4a5e 100644 --- a/backend/requirements.txt +++ b/backend/requirements/common.txt @@ -1,7 +1,5 @@ fastapi==0.68.0 uvicorn==0.14.0 -torch==1.10.2 -torchvision==0.11.3 python-multipart>=0.0.5 gelf-formatter==0.2.1 pyyaml>=5.4.1 diff --git a/backend/requirements/dev.txt b/backend/requirements/dev.txt new file mode 100644 index 00000000..3ab327fc --- /dev/null +++ b/backend/requirements/dev.txt @@ -0,0 +1,3 @@ +--extra-index-url https://download.pytorch.org/whl/cpu +torch==1.13.0 +torchvision==0.14.0 \ No newline at end of file diff --git a/backend/requirements/prod.txt b/backend/requirements/prod.txt new file mode 100644 index 00000000..8f4ca7ca --- /dev/null +++ b/backend/requirements/prod.txt @@ -0,0 +1,3 @@ +--extra-index-url https://download.pytorch.org/whl/cpu +torch==1.13.0+cpu +torchvision==0.14.0+cpu \ No newline at end of file diff --git a/backend/src/model.py b/backend/src/model.py index 6db66c61..496159a1 100644 --- a/backend/src/model.py +++ b/backend/src/model.py @@ -7,12 +7,21 @@ from torchvision import transforms -CLASSES = ['autre_epaule', 'autre_pistolet', 'epaule_a_levier_sous_garde', - 'epaule_a_percussion_silex', 'epaule_a_pompe', 'epaule_a_un_coup', 'epaule_a_verrou', - 'pistolet_a_percussion_silex', 'pistolet_semi_auto_moderne', 'revolver'] - -MODEL_TORCH = Model.efficientnet_b4 -INPUT_SIZE = 380 +CLASSES = ['autre_pistolet', + 'epaule_a_levier_sous_garde', + 'epaule_a_pompe', + 'epaule_a_un_coup_par_canon', + 'epaule_a_verrou', + 'epaule_mecanisme_ancien', + 'epaule_semi_auto_style_chasse', + 'epaule_semi_auto_style_militaire_milieu_20e', + 'pistolet_mecanisme_ancien', + 'pistolet_semi_auto_moderne', + 'revolver', + 'semi_auto_style_militaire_autre'] + +MODEL_TORCH = Model.efficientnet_b7 +INPUT_SIZE = 600 device = torch.device('cpu') diff --git a/backend/tests/test_api.py b/backend/tests/test_api.py index 4ba5c4b5..d84ec6b1 100644 --- a/backend/tests/test_api.py +++ b/backend/tests/test_api.py @@ -48,7 +48,7 @@ def test_upload_and_logs(self): # checks that the json result is as expected self.assertEqual(res["label"], "revolver") - self.assertAlmostEqual(res["confidence"], 99.53, places=1) + self.assertAlmostEqual(res["confidence"], 98.43, 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 @@ -72,7 +72,7 @@ def test_upload_and_logs(self): 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.assertAlmostEqual(log["_bg_confidence"], 98.43, places=1) self.assertTrue(log["_bg_upload_time"]>=0) def test_feedback_and_logs(self): diff --git a/backend/tests/test_model.py b/backend/tests/test_model.py index 9cbd5d0f..2d601cbd 100644 --- a/backend/tests/test_model.py +++ b/backend/tests/test_model.py @@ -51,4 +51,4 @@ def test_predict_image(self): with open(path, 'rb') as f: res = predict_image(self.model, f.read()) self.assertEqual(res[0], "revolver") - self.assertAlmostEqual(res[1], 99.53, places=1) + self.assertAlmostEqual(res[1], 98.43, places=1) diff --git a/frontend/cypress/e2e/get-basegun-result.cy.js b/frontend/cypress/e2e/get-basegun-result.cy.js index e85b0585..de7f16e3 100644 --- a/frontend/cypress/e2e/get-basegun-result.cy.js +++ b/frontend/cypress/e2e/get-basegun-result.cy.js @@ -32,12 +32,12 @@ describe('Get Basegun result', () => { cy.visit('/instructions') cy.getByDataTestid('select-file').as('fileInput') cy.intercept('POST','/api/upload').as('upload') - cy.get('@fileInput').selectFile('./cypress/images/autre-pistolet.jpg', { force: true }) + cy.get('@fileInput').selectFile('./cypress/images/pistolet-ancien-a-percussion-monocoup.jpg', { force: true }) cy.wait('@upload').then(({ response }) => { expect(response.statusCode).to.eq(200) }) cy.url().should('contain','/resultat') - cy.getByDataTestid('legal-category').contains('Catégorie A, B ou D') + cy.getByDataTestid('legal-category').contains('D') cy.getByDataTestid('dummy-button') .should('be.disabled') .contains('Pas de guide de vérification') diff --git a/frontend/cypress/images/autre-pistolet.jpg b/frontend/cypress/images/autre-pistolet.jpg index e5bb32b0..cbc0aa54 100644 Binary files a/frontend/cypress/images/autre-pistolet.jpg and b/frontend/cypress/images/autre-pistolet.jpg differ diff --git a/frontend/cypress/images/pistolet-ancien-a-percussion-monocoup-.jpg b/frontend/cypress/images/pistolet-ancien-a-percussion-monocoup.jpg similarity index 100% rename from frontend/cypress/images/pistolet-ancien-a-percussion-monocoup-.jpg rename to frontend/cypress/images/pistolet-ancien-a-percussion-monocoup.jpg diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 85f7e0fc..007f3fe3 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -1,6 +1,6 @@ { "name": "basegun", - "version": "3.0.0", + "version": "3.1.0", "lockfileVersion": 2, "requires": true, "packages": { diff --git a/frontend/package.json b/frontend/package.json index 17734966..79cd7bb6 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,6 +1,6 @@ { "name": "basegun", - "version": "3.0.0", + "version": "3.1.0", "private": true, "scripts": { "preview": "vite preview", diff --git a/frontend/src/utils/firearms-utils.js b/frontend/src/utils/firearms-utils.js index 40655b0e..3501480d 100644 --- a/frontend/src/utils/firearms-utils.js +++ b/frontend/src/utils/firearms-utils.js @@ -26,50 +26,30 @@ import autreEpauleCartridges from '@/assets/guide-factice/images/autre_epaule/au import autreEpauleBalls from '@/assets/guide-factice/images/autre_epaule/autre-epaule-balls.jpg' export const results = { - revolver: { - displayLabel: 'revolver', - category: 'B ou D', - mention: "B - Soumise à autorisation
D - Libre d'acquisition et de détention", - isDummyTypology: true, - stepsNumber: 4, - }, - pistolet_semi_auto_moderne: { - displayLabel: 'pistolet semi-automatique moderne', - category: 'B', - mention: 'Soumise à autorisation', - isDummyTypology: true, - stepsNumber: 4, - }, - pistolet_a_percussion_silex: { - displayLabel: 'pistolet à mécanisme ancien', - category: 'D', - mention: "Libre d'acquisition et de détention", - isDummyTypology: false, - }, autre_pistolet: { displayLabel: 'pistolet divers', category: 'A, B ou D', mention: "A - Interdite
B - Soumise à autorisation
D - Libre d'acquisition et de détention", isDummyTypology: false, }, - epaule_a_percussion_silex: { - displayLabel: "arme d'épaule à mécanisme ancien", - category: 'D', - mention: "Libre d'acquisition et de détention", - isDummyTypology: false, - }, - epaule_a_un_coup: { - displayLabel: "arme d'épaule à un coup par canon", - category: 'C', - mention: 'Soumise à déclaration', - isDummyTypology: false, - }, epaule_a_levier_sous_garde: { displayLabel: "arme d'épaule à levier de sous-garde", category: 'B ou C', mention: 'B - Soumise à autorisation
C - Soumise à déclaration', isDummyTypology: false, }, + epaule_a_pompe: { + displayLabel: "arme d'épaule à pompe", + category: 'B ou C', + mention: 'B - Soumise à autorisation
C - Soumise à déclaration', + isDummyTypology: false, + }, + epaule_a_un_coup_par_canon: { + displayLabel: "arme d'épaule à un coup ou un coup par canon", + category: 'C', + mention: 'Soumise à déclaration', + isDummyTypology: false, + }, epaule_a_verrou: { displayLabel: "arme d'épaule à verrou", category: 'B ou C', @@ -77,16 +57,48 @@ export const results = { isDummyTypology: false, stepsNumber: 4, }, - epaule_a_pompe: { - displayLabel: "arme d'épaule à pompe", + epaule_mecanisme_ancien: { + displayLabel: "arme d'épaule à mécanisme ancien", + category: 'D', + mention: "Libre d'acquisition et de détention", + isDummyTypology: false, + }, + epaule_semi_auto_style_chasse: { + displayLabel: "arme d'épaule semi-automatique", category: 'B ou C', mention: 'B - Soumise à autorisation
C - Soumise à déclaration', isDummyTypology: false, }, - autre_epaule: { - displayLabel: "arme d'épaule non manuelle", + epaule_semi_auto_style_militaire_milieu_20e: { + displayLabel: "arme d'épaule semi-automatique ou automatique", category: 'A, B ou C', mention: 'A - Interdite
B - Soumise à autorisation
C - Soumise à déclaration', + isDummyTypology: false, + }, + pistolet_semi_auto_moderne: { + displayLabel: 'pistolet semi-automatique', + category: 'B', + mention: 'Soumise à autorisation', + isDummyTypology: true, + stepsNumber: 4, + }, + pistolet_mecanisme_ancien: { + displayLabel: 'pistolet à mécanisme ancien', + category: 'D', + mention: "Libre d'acquisition et de détention", + isDummyTypology: false, + }, + revolver: { + displayLabel: 'revolver', + category: 'B ou D', + mention: "B - Soumise à autorisation
D - Libre d'acquisition et de détention", + isDummyTypology: true, + stepsNumber: 4, + }, + semi_auto_style_militaire_autre: { + displayLabel: "arme semi-automatique ou automatique", + category: 'A, B ou C', + mention: 'A - Interdite
B - Soumise à autoriszation
C - Soumise à déclaration', isDummyTypology: true, stepsNumber: 4, }, @@ -110,8 +122,8 @@ export const guideFacticeSelectOption = { video: pistoletSemiAutoModerne2Video, }, }, - autre_epaule_text_option: 'Sélectionner ce que vous voyez sur l’arme', - autre_epaule: { + semi_auto_style_militaire_autre_text_option: 'Sélectionner ce que vous voyez sur l’arme', + semi_auto_style_militaire_autre: { bouton_dessus: { label: 'bouton au-dessus chargeur', value: 'bouton_dessus', @@ -186,7 +198,7 @@ export const guideFacticeSelectAmmo = { img_ammo: pistoletSemiAutoModerneBalls, }, }, - autre_epaule: { + semi_auto_style_militaire_autre: { cartouches: { label: 'cartouches', value: 'cartouches', diff --git a/frontend/src/views/About.vue b/frontend/src/views/About.vue index 68268919..3ba10fda 100644 --- a/frontend/src/views/About.vue +++ b/frontend/src/views/About.vue @@ -54,7 +54,7 @@ const imgs = ref([

A ce jour, Basegun permet de prendre en photo une arme à feu et d'obtenir un - résultat parmi 10 typologies possibles. Ce résultat donne une indication sur la ou les catégories légales + résultat parmi 12 typologies possibles. Ce résultat donne une indication sur la ou les catégories légales à laquelle l'arme appartient.