Skip to content

Commit

Permalink
Merge pull request #1 from devansh-shah-11/merge-code-mark-1
Browse files Browse the repository at this point in the history
Merge code mark 1
  • Loading branch information
Devasy23 authored Mar 7, 2024
2 parents 7c47cf0 + 47cc66b commit 32655af
Show file tree
Hide file tree
Showing 33 changed files with 2,013 additions and 71 deletions.
10 changes: 8 additions & 2 deletions .github/workflows/python-app.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install flake8 pytest
pip install flake8 pytest pytest-cov
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
- name: Lint with flake8
run: |
Expand All @@ -36,4 +36,10 @@ jobs:
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
- name: Test with pytest
run: |
pytest
pytest --cov .
continue-on-error: true
- name: Upload coverage reports to Codecov
uses: codecov/[email protected]
with:
token: ${{ secrets.CODECOV_TOKEN }}
slug: devansh-shah-11/FaceRec
140 changes: 139 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,142 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
.pybuilder/
target/

# Jupyter Notebook
.ipynb_checkpoints

# IPython
profile_default/
ipython_config.py

# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version

# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock

# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/

# Celery stuff
celerybeat-schedule
celerybeat.pid

# SageMath parsed files
*.sage.py

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
.dmypy.json
dmypy.json

# Pyre type checker
.pyre/

# pytype static type analyzer
.pytype/

# Cython debug symbols
cython_debug/
venv/
*.pyc
.vscode/
__pycache__/
__pyc
18 changes: 18 additions & 0 deletions API/_init_.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import uvicorn
from fastapi import FastAPI

from API import route

Fastapp = FastAPI()
# API Router
Fastapp.include_router(route.router)


@Fastapp.get("/")
def read_root():
return {"Hello": "FASTAPI"}


# function to run server of FastAPI
def run_fastapi_app():
uvicorn.run(Fastapp, host="127.0.0.1", port=8000)
24 changes: 24 additions & 0 deletions API/database.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from datetime import datetime

from pymongo import MongoClient


class Database:
def __init__(self, uri="mongodb://localhost:27017/", db_name="ImageDB"):
self.client = MongoClient(uri)
self.db = self.client[db_name]

def find(self, collection, query=None):
return self.db[collection].find(query)

def insert_one(self, collection, document):
return self.db[collection].insert_one(document)

def find_one(self, collection, filter, projection=None):
return self.db[collection].find_one(filter=filter, projection=projection)

def find_one_and_delete(self, collection, query):
return self.db[collection].find_one_and_delete(query)

def update_one(self, collection, query, update):
return self.db[collection].update_one(query, update)
185 changes: 185 additions & 0 deletions API/route.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
import base64
import json
import logging
import os
from datetime import datetime
from io import BytesIO

from bson import ObjectId
from deepface import DeepFace
from fastapi import APIRouter, Form, HTTPException, Response
from matplotlib import pyplot as plt
from PIL import Image
from pydantic import BaseModel
from pymongo import MongoClient

from API.database import Database

# Create a logger object
logger = logging.getLogger(__name__)
# Create a file handler
handler = logging.FileHandler("log.log")
handler.setLevel(logging.INFO)
# Create a logging format
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
handler.setFormatter(formatter)

router = APIRouter()

# To create connection with Mongodb
# mongodb_uri = "mongodb://localhost:27017/"
# port = 8000
# client = MongoClient(mongodb_uri, port)

# db = client["ImageDB"]
client = Database()

collection = "faceEntries"


# Models for the data to be sent and received by the server
class Employee(BaseModel):
EmployeeCode: int
Name: str
gender: str
Department: str
Image: str


class UpdateEmployee(BaseModel):
Name: str
gender: str
Department: str
Image: str


# To create new entries of employee
@router.post("/create_new_faceEntry")
async def create_new_faceEntry(Employee: Employee):
Name = Employee.Name
EmployeeCode = Employee.EmployeeCode
gender = Employee.gender
Department = Employee.Department
encoded_image = Employee.Image
time = datetime.now()
img_recovered = base64.b64decode(encoded_image) # decode base64string
# print(img_recovered)
pil_image = Image.open(BytesIO(img_recovered))
image_filename = f"{Name}.png"
pil_image.save(image_filename)
# print path of the current working directory
pil_image.save(f"Images\dbImages\{Name}.jpg")
# Extract the face from the image
face_image_data = DeepFace.extract_faces(
image_filename, detector_backend="mtcnn", enforce_detection=False
)
# Calculate the embeddings of the face image
plt.imsave(f"Images/Faces/{Name}.jpg", face_image_data[0]["face"])
embeddings = DeepFace.represent(
image_filename, model_name="Facenet", detector_backend="mtcnn"
)
os.remove(image_filename)
# Store the data in the database
client.insert_one(
collection,
{
"EmployeeCode": EmployeeCode,
"Name": Name,
"gender": gender,
"Department": Department,
"time": time,
"embeddings": embeddings,
"Image": encoded_image,
},
)
# db.faceEntries.insert_one(

# )
return {"message": "Face entry created successfully"}


# To display all records
@router.get("/Data/", response_model=list[Employee])
async def get_employees():
employees_mongo = client.find(collection)
employees = [
Employee(
EmployeeCode=int(employee.get("EmployeeCode", 0)),
Name=employee.get("Name", "N/A"),
gender=employee.get("gender", "N/A"),
Department=employee.get("Department", "N/A"),
Image=employee.get("Image", "N/A"),
)
for employee in employees_mongo
]
return employees


# To display specific record info
@router.get("/read/{EmployeeCode}", response_class=Response)
async def read_employee(EmployeeCode: int):
try:
# logger.info(f"Start {EmployeeCode}")
items = client.find_one(
collection,
filter={"EmployeeCode": EmployeeCode},
projection={
"Name": True,
"gender": True,
"Department": True,
"Image": True,
"_id": False,
},
)
if items:
json_items = json.dumps(items)
return Response(
content=bytes(json_items, "utf-8"), media_type="application/json"
)
else:
return Response(
content=json.dumps({"message": "Employee not found"}),
media_type="application/json",
status_code=404,
)
except Exception as e:
print(e)


# For updating existing record
@router.put("/update/{EmployeeCode}", response_model=str)
async def update_employees(EmployeeCode: int, Employee: UpdateEmployee):
try:
# logger.warning("Updating Start")
user_id = client.find_one(
collection, {"EmployeeCode": EmployeeCode}, projection={"_id": True}
)
print(user_id)
if not user_id:
raise HTTPException(status_code=404, detail="Employee not found")
Employee_data = Employee.model_dump(by_alias=True, exclude_unset=True)
# logger.info(f"Employee data to update: {Employee_data}")
try:
update_result = client.update_one(
collection,
filter={"_id": ObjectId(user_id["_id"])},
update={"$set": Employee_data},
)
if update_result.modified_count == 0:
raise HTTPException(status_code=400, detail="No data was updated")
return "Updated Successfully"
except Exception as e:
# logger.error(f"Error while updating: {e}")
raise HTTPException(status_code=500, detail="Internal server error")
except Exception as e:
# logger.error(f"Error while fetching user_id: {e}")
raise HTTPException(status_code=500, detail="Internal server error")


# To delete employee record
@router.delete("/delete/{EmployeeCode}")
async def delete_employees(EmployeeCode: int):
print(EmployeeCode)
client.find_one_and_delete(collection, {"EmployeeCode": EmployeeCode})

return {"Message": "Successfully Deleted"}
Loading

0 comments on commit 32655af

Please sign in to comment.