Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Original codes added and new html pages added. #1

Merged
merged 1 commit into from
Apr 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
version: '3.8'

services:
web-app:
build:
context: ./web-app
dockerfile: ./Dockerfile
ports:
- "10000:5000"
env_file:
- .env
depends_on:
- db

machine-learning-client:
build:
context: ./machine-learning-client
dockerfile: ./Dockerfile
ports:
- "5002:5002"
env_file:
- .env
depends_on:
- db


db:
image: mongo
ports:
- "27017:27017"
volumes:
- ./data:/data/db


18 changes: 18 additions & 0 deletions machine-learning-client/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# in Docker, it is common to base a new image on a previously-created image
# Use an official Python runtime image as a parent image to base this image on
FROM python:3
# Set the working directory within the image to /app
WORKDIR /main
# the ADD command is how you add files from your local machine into a Docker image
# Copy the current directory contents into the container at /app
ADD . /main
# Install any needed packages specified in requirements.txt
# in Python, a requirements.txt file is a way of indicating dependencies in a way that the package manager, pip, can understand
RUN pip install --trusted-host pypi.python.org -r requirements.txt
# by default Docker containers are closed off to the external world
# Make port 80 available to the world outside this container
EXPOSE 5002
# Define an environment variable... this will be available to programs running inside the container
ENV NAME World
# Run app.py when the container launches
CMD ["python", "main.py"]
13 changes: 13 additions & 0 deletions machine-learning-client/Pipfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"

[packages]
pylint = "*"
black = "*"

[dev-packages]

[requires]
python_version = "3.10"
Binary file added machine-learning-client/RestaurantReceipt1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
123 changes: 123 additions & 0 deletions machine-learning-client/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
import os
from flask import Flask, request, jsonify
import requests
import pymongo
from pymongo import MongoClient
import json
from dotenv import load_dotenv
from bson import ObjectId

import logging

logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)

# Use receipt-OCR.py to get response1.json
# (can only do this a couple times an hour with the test API key)

# Load response1.json
with open("response1.json", "r") as f:
data = json.load(f)

print('Receipt Keys:', data['receipts'][0].keys())
items = data['receipts'][0]['items']
print()
print(f"Your purchase at {data['receipts'][0]['merchant_name']}")

for item in items:
print(f"{item['description']} - {data['receipts'][0]['currency']} {item['amount']}")
print("-" * 20)
print(f"Subtotal: {data['receipts'][0]['currency']} {data['receipts'][0]['subtotal']}")
print(f"Tax: {data['receipts'][0]['currency']} {data['receipts'][0]['tax']}")
print("-" * 20)
print(f"Total: {data['receipts'][0]['currency']} {data['receipts'][0]['total']}")
# print(data['receipts'])


# load credentials and configuration options from .env file
# if you do not yet have a file named .env, make one based on the templatpip e in env.example
load_dotenv() # take environment variables from .env.

# instantiate the app
app = Flask(__name__)
app.secret_key = 'a_unique_and_secret_key'
# # turn on debugging if in development mode
if os.getenv("FLASK_ENV", "development") == "development":
# # turn on debugging, if in development
app.debug = True # debug mnode

# connect to the database
cxn = pymongo.MongoClient(os.getenv("MONGO_URI"))
db = cxn[os.getenv("MONGO_DBNAME")] # store a reference to the database

@app.route('/predict', methods=['POST'])
def pretdict_endpoint():
# Get the image data from the request
request_data = request.get_json() # Extract JSON data from the request
if 'Object_ID' not in request_data:
return jsonify({'error': 'Object_ID not found in request data'}), 400

Object_ID = ObjectId(request_data['Object_ID'])
logger.debug('OBJECT_ID MESSAGE:', Object_ID)
#image = db.receipts.find_one({"_id": Object_ID})['image']

# Here, you would add the code to perform OCR on the image
# For now, let's assume you have a function called perform_ocr that does this

# Uncomment next line to perform OCR
data = perform_ocr(Object_ID)
#data = json.load(open("response1.json", "r"))

# Connect to your collection (replace 'mycollection' with your collection name)
collection = db['receipts']

# Prepare the data to be inserted into the database
receipt = data['receipts'][0]
receipt_data = {
'receipt_name': receipt['merchant_name'],
'currency': receipt['currency'],
'items': [{'description': item['description'], 'amount': item['amount']} for item in receipt['items']],
'total': receipt['total'],
'tax': receipt['tax'],
'tip': receipt['tip'],
'subtotal': receipt['subtotal'],
}
logger.debug(receipt_data)

# Update the document with given ObjectId
collection.update_one({'_id': Object_ID}, {'$set': receipt_data})
inserted_id = Object_ID

# Return the inserted_id as a JSON response
return jsonify({'_id': str(inserted_id)})

def perform_ocr(Object_ID):
logger.debug("starting perform_ocr function...") # debug
url = "https://ocr.asprise.com/api/v1/receipt"
image_data = db.receipts.find_one({"_id": Object_ID})['image']
file_path = f"receipt_{Object_ID}.jpg" # Set the file path to save the image
logger.debug("file path: %s", file_path) # debug
with open(file_path, "wb") as f:
f.write(image_data)
file_path = file_path.replace('\x00', '') # Remove any null bytes from the file path


# Get response (can only do this a couple times with the test API key)
res = requests.post(url,
data = {
'api_key': 'TEST',
'recognizer': 'auto',
'ref_no': 'ocr_python_123'
},

files = {
'file': open(file_path, "rb")
})

with open("response.json", "w") as f:
f.write(res.text)

return res.json()

if __name__ == '__main__':
app.run(host='0.0.0.0', port=5002) # Run the app
6 changes: 6 additions & 0 deletions machine-learning-client/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
pymongo
pylint
black
requests
Flask
python-dotenv
166 changes: 166 additions & 0 deletions machine-learning-client/response1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
{
"ocr_type" : "receipts",
"request_id" : "P_72.80.97.228_luxbmz9s_bz6",
"ref_no" : "ocr_python_123",
"file_name" : "RestaurantReceipt1.png",
"request_received_on" : 1712965847825,
"success" : true,
"image_width" : 812,
"image_height" : 1354,
"image_rotation" : 0,
"recognition_completed_on" : 1712965848215,
"receipts" : [ {
"merchant_name" : "HARBOR LANE CAFE",
"merchant_address" : "HARBOR LANE CAFE",
"merchant_phone" : null,
"merchant_website" : null,
"merchant_tax_reg_no" : null,
"merchant_company_reg_no" : null,
"region" : null,
"mall" : null,
"country" : "US",
"state" : "IL",
"city" : "CHICAGO",
"receipt_no" : null,
"date" : "2019-11-20",
"time" : null,
"items" : [ {
"amount" : 14.98,
"category" : null,
"description" : "Tacos Del Mal Shrimp",
"flags" : "",
"qty" : 1,
"remarks" : null,
"tags" : null,
"unitPrice" : null
}, {
"amount" : 12.50,
"category" : null,
"description" : "Especial Salad Chicken",
"flags" : "",
"qty" : 1,
"remarks" : null,
"tags" : null,
"unitPrice" : null
}, {
"amount" : 1.99,
"category" : null,
"description" : "Fountain Beverage",
"flags" : "",
"qty" : 1,
"remarks" : null,
"tags" : null,
"unitPrice" : null
} ],
"currency" : "USD",
"total" : 31.39,
"subtotal" : 29.47,
"tax" : 1.92,
"service_charge" : null,
"tip" : null,
"payment_method" : null,
"payment_details" : null,
"credit_card_type" : null,
"credit_card_number" : null,
"ocr_text" : " HARBOR LANE CAFE\n 3941 GREEN OAKS BLVD\n CHICAGO, IL\n SALE\n 11/20/2019 11:05 AM\n BATCH #: 01A2A\n APPR #: 34362\n TRACE #: 9\n VISA 3483\n 1 Tacos Del Mal Shrimp $14.98\n 1 Especial Salad Chicken $12.50\n 1 Fountain Beverage $1.99\n SUBTOTAL: $29.47\n TAX: $1.92\n TOTAL: $31.39\n TIP:\n TOTAL:\n APPROVED\n THANK YOU\n CUSTOMER COPY",
"ocr_confidence" : 98.50,
"width" : 596,
"height" : 1111,
"avg_char_width" : 16.9954,
"avg_line_height" : 28.3333,
"conf_amount" : 83,
"source_locations" : {
"date" : [ [ {
"x" : 46,
"y" : 216
}, {
"x" : 240,
"y" : 216
}, {
"x" : 240,
"y" : 246
}, {
"x" : 46,
"y" : 246
} ] ],
"total" : [ [ {
"x" : 275,
"y" : 696
}, {
"x" : 381,
"y" : 696
}, {
"x" : 381,
"y" : 726
}, {
"x" : 275,
"y" : 726
} ] ],
"subtotal" : [ [ {
"x" : 276,
"y" : 615
}, {
"x" : 384,
"y" : 615
}, {
"x" : 384,
"y" : 646
}, {
"x" : 276,
"y" : 646
} ] ],
"merchant_name" : [ [ {
"x" : 40,
"y" : 13
}, {
"x" : 357,
"y" : 15
}, {
"x" : 357,
"y" : 47
}, {
"x" : 40,
"y" : 46
} ] ],
"doc" : [ [ {
"x" : 24,
"y" : -40
}, {
"x" : 679,
"y" : -40
}, {
"x" : 679,
"y" : 1181
}, {
"x" : 24,
"y" : 1181
} ] ],
"tax" : [ [ {
"x" : 277,
"y" : 656
}, {
"x" : 361,
"y" : 656
}, {
"x" : 361,
"y" : 685
}, {
"x" : 277,
"y" : 685
} ] ],
"merchant_address" : [ [ {
"x" : 24,
"y" : 11
}, {
"x" : 373,
"y" : 13
}, {
"x" : 373,
"y" : 49
}, {
"x" : 24,
"y" : 48
} ] ]
}
} ]
}
12 changes: 12 additions & 0 deletions web-app/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# docs: https://hub.docker.com/_/python
FROM python:3.8-slim-buster

WORKDIR /web_app

COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

EXPOSE 10000
CMD [ "python3", "-m" , "flask", "run", "--host=0.0.0.0"]
13 changes: 13 additions & 0 deletions web-app/Pipfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"

[packages]
pylint = "*"
black = "*"

[dev-packages]

[requires]
python_version = "3.10"
Loading
Loading