Skip to content

Commit 5004d2b

Browse files
authored
Merge pull request #25 from brain-facens/develop
Develop
2 parents 1d480c9 + 35e734d commit 5004d2b

19 files changed

+342
-45
lines changed

.github/workflows/python-app.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ name: Python application
55

66
on:
77
push:
8-
branches: [ "master" ]
8+
branches: [ "main", "develop" ]
99
pull_request:
10-
branches: [ "master" ]
10+
branches: [ "main", "develop" ]
1111

1212
permissions:
1313
contents: read
@@ -34,6 +34,8 @@ jobs:
3434
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
3535
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
3636
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
37+
- name: Run api
38+
run: python src/field_vision_api/main.py
3739
- name: Test with pytest
3840
run: |
3941
pytest

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
*.drawio
22
__pycache__/
3-
3+
.pytest_cache/
44
node_modules/
55
.expo/
66
dist/

README.md

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ https://github.com/brain-facens/OCR-notas/assets/64169072/8078be88-cb17-4616-9e0
44

55
API for processing text on invoices, with the aim of identifying relevant fields on an invoice and optimizing bonus or validation systems. Making life easier for logisticians, merchants and managers, the application has an interface that captures images from the webcam, processes the image using OCR and provides a visualization of the results obtained.
66

7+
## Docs
8+
[Visit our wiki](https://github.com/brain-facens/FieldVision-AI/wiki)
9+
710
## First Steps
811

912
This project was developed to run a web interface, where the user will have access to the image capture system and the data processed from that image. Follow the steps below to use this project, the stable version is in the main branch.
@@ -20,10 +23,10 @@ The following requirements should ideally be met for proper operation:
2023
- Create a virtual environment for the project if you want to work without conda;
2124

2225
```
23-
conda create --name paddle_env python=3.8 --channel https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
26+
conda create --name fielvision python=3.8 --channel https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
2427
2528
# Activate the environment
26-
conda activate paddle_env
29+
conda activate fielvision
2730
```
2831

2932
---
@@ -38,11 +41,13 @@ Local:
3841

3942
```
4043
# Activate the environment
41-
conda activate paddle_env
44+
conda activate fielvision
4245
43-
git clone https://github.com/brain-facens/OCR-notas.git
46+
# Clone repository
47+
git clone https://github.com/brain-facens/FieldVision-AI.git
4448
45-
cd OCR-notas
49+
# Install requirements
50+
cd FieldVision-AI/
4651
pip install -r requirements.txt
4752
```
4853

@@ -58,8 +63,11 @@ docker pull brain20/ocr-notas
5863
Local:
5964

6065
```
61-
# applicable filter of up to 3 words
62-
python main.py --filter <fist,second,third,...>
66+
# Applicable filter of up to 3 words
67+
# python src/field_vision_API/main.py <fist, second, third>
68+
69+
# Run API
70+
python src/field_vision_API/main.py
6371
```
6472

6573
Docker:

requirements.txt

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,11 @@
1-
shapely
2-
scikit-image
3-
imgaug
4-
pyclipper
5-
lmdb
6-
tqdm
7-
numpy
8-
visualdl
9-
rapidfuzz
10-
opencv-python<=4.6.0.66
11-
opencv-contrib-python<=4.6.0.66
12-
cython
13-
lxml
14-
premailer
15-
openpyxl
16-
attrdict
17-
PyMuPDF<1.21.0
18-
Pillow
19-
pyyaml
20-
fastapi[all]
21-
paddleocr
22-
paddlepaddle
1+
paddleocr==2.7.0.3
2+
typing==3.7.4.3
3+
numpy==1.24.4
4+
fastapi==0.104.0
5+
pydantic==2.4.2
6+
uvicorn==0.23.2
7+
opencv-python==4.6.0.66
8+
paddlepaddle==2.5.1
9+
python-multipart==0.0.6
10+
requests==2.31.0
11+
pytest==7.4.3

src/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# src
2+

src/field_vision_api/README.md

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# FieldVision API
2+
API for processing text on invoices, with the aim of identifying relevant fields on an invoice and optimizing bonus or validation systems. Making life easier for logisticians, merchants and managers, the application has an interface that captures images from the webcam, processes the image using OCR and provides a visualization of the results obtained.
3+
4+
Follow the steps bellow to install the FieldVision API:
5+
6+
```
7+
# Clone repository
8+
git clone https://github.com/brain-facens/FieldVision-AI.git
9+
10+
# Install requirements
11+
cd FieldVision-AI/
12+
pip install -r requirements.txt
13+
14+
# Run API
15+
python src/field_vision_API/main.py
16+
```
17+
18+
## API Methods
19+
Below are the methods present in the FieldVision API and their respective functions.
20+
21+
| API Call | Action|
22+
|----------|-------|
23+
| GET / | Home path |
24+
| GET /v1/result/ | Get the filtered result |
25+
| GET /v1/raw_result/ | Get the latest raw result |
26+
| GET /v1/filter/ | Get the latest word filter |
27+
| POST /v1/post_image/ | Upload image |
28+
| PUT /v1/filter/ | Update the filter |
29+
30+
31+
32+
33+
## Example Request Scripts
34+
Below are the scripts that make it possible to request the methods present in the API.
35+
36+
#### **GET** methods:
37+
38+
```
39+
import pytest
40+
import requests
41+
42+
def test_api_call_root(url = <API_url>):
43+
response = requests.get(url)
44+
return response
45+
```
46+
---
47+
#### **PUT** methods:
48+
49+
```
50+
import pytest
51+
import requests
52+
53+
def test_api_put_result(url = <API_url>):
54+
payload={
55+
"filter": [
56+
"total"
57+
]
58+
}
59+
60+
response = requests.put(url, json=payload)
61+
return response
62+
```
63+
---
64+
#### **POST** methods:
65+
66+
```
67+
import pytest
68+
import requests
69+
70+
def test_api_put_result(url = <API_url>):
71+
payload={
72+
"filter": [
73+
"total"
74+
]
75+
}
76+
77+
response = requests.put(url, json=payload)
78+
return response
79+
```

src/field_vision_api/__init__.py

Whitespace-only changes.

src/field_vision_api/core/__init__.py

Whitespace-only changes.

python_scripts/main.py renamed to src/field_vision_api/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
from fastapi import FastAPI, File, UploadFile
2424
from pydantic import BaseModel # E0611, pylint: disable=no-name-in-module
2525
import uvicorn
26-
from utils import (ocr_process, filter_process, read_imagefile,
26+
from util.utils import (ocr_process, filter_process, read_imagefile, # E0401, pylint: disable=import-error
2727
list_of_strings, Results, Filter)
2828

2929

docs/utils.html renamed to src/field_vision_api/util/README.md

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -198,12 +198,16 @@
198198
&nbsp;<br>
199199
...<br>
200200
Args:<br>
201-
&nbsp;&nbsp;&nbsp;&nbsp;img:&nbsp;image&nbsp;to&nbsp;process.<br>
202-
&nbsp;<br>
203-
Returns:<br>
204-
&nbsp;&nbsp;&nbsp;&nbsp;Result&nbsp;of&nbsp;OCR&nbsp;processing&nbsp;on&nbsp;the&nbsp;image.</tt></dd></dl>
205-
<dl><dt><a name="-read_imagefile"><strong>read_imagefile</strong></a>(data)</dt><dd><tt>Image&nbsp;processing.<br>
206-
&nbsp;<br>
201+
&nbsp;&nbsp;&nbsp;&nbsp;Frame&nbsp;with&nbsp;rgb&nbsp;color&nbsp;pattern&nbsp;and&nbsp;processed&nbsp;from&nbsp;byte&nbsp;array&nbsp;to&nbsp;ndarray.</tt></dd></dl>
202+
</td></tr></table><p>
203+
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
204+
<tr bgcolor="#55aa55">
205+
<td colspan=3 valign=bottom>&nbsp;<br>
206+
<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
207+
208+
<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
209+
<td width="100%"><strong>List</strong> = typing.List</td></tr></table>
210+
</body></html>
207211
...<br>
208212
Args:<br>
209213
&nbsp;&nbsp;&nbsp;&nbsp;data:&nbsp;API&nbsp;buffer&nbsp;image.<br>

src/field_vision_api/util/__init__.py

Whitespace-only changes.

python_scripts/utils.py renamed to src/field_vision_api/util/utils.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ def __init__(self, filter_:List[str]) -> None:
5555
"""
5656
self._filter_words = filter_
5757

58-
def set_filter(self, new_filter):
58+
def set_filter(self, new_filter) -> None:
5959
"""
6060
Setter for filter words.
6161
@@ -68,7 +68,7 @@ def set_filter(self, new_filter):
6868
"""
6969
self._filter_words = new_filter
7070

71-
def get_filter(self) -> List:
71+
def get_filter(self) -> list:
7272
"""
7373
Getter for filter words.
7474
@@ -126,7 +126,7 @@ def set_results(self, new_results) -> None:
126126
"""
127127
self._results = new_results
128128

129-
def get_results(self) -> List:
129+
def get_results(self) -> list:
130130
"""
131131
Getter for OCR processing results.
132132
@@ -140,7 +140,7 @@ def get_results(self) -> List:
140140
return self._results
141141

142142

143-
def list_of_strings(arg) -> List:
143+
def list_of_strings(arg) -> list:
144144
"""
145145
Get list of strings from user's filter input.
146146
@@ -170,7 +170,7 @@ def read_imagefile(data) -> np.ndarray:
170170
cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) # E1101, pylint: disable=no-member
171171
return frame
172172

173-
def ocr_process(img) -> List:
173+
def ocr_process(img) -> list:
174174
"""
175175
OCR processing.
176176
@@ -186,7 +186,7 @@ def ocr_process(img) -> List:
186186
return result
187187

188188

189-
def filter_process(result, phrases) -> List:
189+
def filter_process(result, phrases) -> list:
190190
"""
191191
Filter processing.
192192

tests/README.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
## Test Cases for API Testing
2+
To test the API, some test cases were created, which are shown in the table below.
3+
4+
| Test Scenario Category | Test Action Category | Test Action Description |
5+
|------------------------|----------------------|-------------------------|
6+
| ***1 Basic Positive Tests*** |||
7+
| Execute API call with valid required parameters| Validate status code:| 1. All requests should return 2XX HTTP status code <br> 2. Returned status code is according to spec: <br> - 200 OK for **GET**, **POST** and **PUT** request <br> 3. Validate returns with expected API data: <br> - **GET** /, returns: Information for user to found the API docs <br> - **GET** /v1/result/, returns: Information for user to found the API docs <br> - **GET** /v1/raw_result/, returns: Latest OCR processing raw result <br> - **GET** /v1/filter/, returns the latest word filter on API <br> - **POST** /v1/post_image/, returns: Information for user to found the API docs <br> - **PUT** /v1/filter/, returns: The new filter |
8+
9+
To run the tests, the API must be running. After checking this, run the commands below:
10+
```
11+
# Go to the repository's root folder
12+
cd FieldVision-AI
13+
14+
# Run pytest
15+
pytest
16+
```
17+
---
18+
19+
## Example Test scripts
20+
21+
How to test **GET** methods:
22+
23+
```
24+
import pytest
25+
import requests
26+
27+
def test_api_call_root(url = <API_url>):
28+
response = requests.get(url)
29+
assert response.status_code == 200, "Failed!"
30+
```
31+
---
32+
How to test **PUT** methods:
33+
34+
```
35+
import pytest
36+
import requests
37+
38+
def test_api_put_result(url = <API_url>):
39+
payload={
40+
"filter": [
41+
"total"
42+
]
43+
}
44+
45+
response = requests.put(url, json=payload)
46+
assert response.status_code == 200, "Failed!"
47+
```
48+
---
49+
How to test **POST** methods:
50+
51+
```
52+
import pytest
53+
import requests
54+
55+
def test_api_put_result(url = <API_url>):
56+
payload={
57+
"filter": [
58+
"total"
59+
]
60+
}
61+
62+
response = requests.put(url, json=payload)
63+
assert response.status_code == 200, "Failed!"
64+
```

tests/test_get_filter.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
"""
2+
Script to test GET method endpoint /v1/filter/.
3+
"""
4+
5+
import pytest # W0611, pylint: disable=unused-import
6+
import requests
7+
8+
def test_api_get_filter(url = "http://0.0.0.0:8085/v1/filter/") -> None:
9+
"""
10+
Test for endpoint filter result /v1/filter/.
11+
12+
...
13+
Args:
14+
url: API url.
15+
16+
Returns:
17+
None.
18+
"""
19+
response = requests.get(url, timeout=10)
20+
assert response.status_code == 200, "Failed!\n"
21+
response = response.json()
22+
assert response['latest_filter'] is None, 'Result error!\n'

tests/test_get_raw_result.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
"""
2+
Script to test GET method endpoint /v1/raw_result/.
3+
"""
4+
import pytest # W0611, pylint: disable=unused-import
5+
import requests
6+
7+
def test_api_get_raw_result(url = "http://0.0.0.0:8085/v1/raw_result/"):
8+
"""
9+
Test for endpoint raw result /v1/raw_result/.
10+
11+
...
12+
Args:
13+
url: API url.
14+
15+
Returns:
16+
None.
17+
"""
18+
response = requests.get(url, timeout=10)
19+
assert response.status_code == 200, "Failed!"
20+
response = response.json()
21+
assert isinstance(response['latest_result'], list), 'Result error!'

0 commit comments

Comments
 (0)