saifulbabo commited on
Commit
12f678a
1 Parent(s): 257fb52

add application file

Browse files
.gitignore ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ .vercel
2
+ venv
3
+ .venv
4
+ .idea
5
+ __pycache__
Dockerfile ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.9
2
+
3
+ WORKDIR /code
4
+
5
+ COPY requirements.txt ./
6
+
7
+ RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
8
+
9
+ RUN useradd -m -u 1000 user
10
+
11
+ USER user
12
+
13
+ ENV HOME=/home/user \
14
+ PATH=/home/user/.local/bin:$PATH
15
+
16
+ WORKDIR $HOME/app
17
+
18
+ COPY --chown=user . $HOME/app/
19
+
20
+ CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "7860" "--workers", "2"]
api/index.py ADDED
@@ -0,0 +1 @@
 
 
1
+ from src.index import app
main.py ADDED
@@ -0,0 +1 @@
 
 
1
+ from api.index import app
requirements.txt ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ fastapi==0.88.0
2
+ Pillow==9.5.0
3
+ protobuf==4.25.0
4
+ python-multipart==0.0.6
5
+ sentencepiece==0.1.99
6
+ # transformers==4.35.0
7
+ transformers[torch]
8
+ uvicorn==0.20.0
src/__main__.py ADDED
File without changes
src/dtos/ISayHelloDto.py ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ from pydantic import BaseModel
2
+
3
+ class ISayHelloDto(BaseModel):
4
+ message: str
src/index.py ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, File, UploadFile, Form
2
+ from fastapi.responses import JSONResponse
3
+ from fastapi.middleware.cors import CORSMiddleware
4
+ from transformers import TrOCRProcessor, VisionEncoderDecoderModel
5
+ import requests
6
+ from PIL import Image
7
+ import io
8
+ import base64
9
+ from src.dtos.ISayHelloDto import ISayHelloDto
10
+
11
+ app = FastAPI()
12
+
13
+ # Enable CORS for all origins
14
+ app.add_middleware(
15
+ CORSMiddleware,
16
+ allow_origins=["*"],
17
+ allow_credentials=True,
18
+ allow_methods=["*"],
19
+ allow_headers=["*"],
20
+ )
21
+
22
+ processor = TrOCRProcessor.from_pretrained("microsoft/trocr-small-printed")
23
+ model = VisionEncoderDecoderModel.from_pretrained("src/model/captcha")
24
+
25
+ def read_image(file) -> Image.Image:
26
+ image = Image.open(io.BytesIO(file))
27
+ return image
28
+
29
+ def read_base64_image(base64_data) -> Image.Image:
30
+ base64_bytes = base64.b64decode(base64_data)
31
+ image = Image.open(io.BytesIO(base64_bytes))
32
+ return image
33
+
34
+ def process_image(image):
35
+ # prepare image
36
+ pixel_values = processor(image, return_tensors="pt").pixel_values
37
+
38
+ # generate (no beam search)
39
+ generated_ids = model.generate(pixel_values)
40
+
41
+ # decode
42
+ generated_text = processor.batch_decode(generated_ids, skip_special_tokens=True)[0]
43
+
44
+ return generated_text
45
+
46
+ @app.get("/")
47
+ async def root():
48
+ return {"message": "Hello World"}
49
+
50
+
51
+ @app.get("/hello/{name}")
52
+ async def say_hello(name: str):
53
+ return {"message": f"Hello {name}"}
54
+
55
+
56
+ @app.post("/hello")
57
+ async def hello_message(dto: ISayHelloDto):
58
+ return {"message": f"Hello {dto.message}"}
59
+
60
+
61
+ @app.post("/extract-text")
62
+ async def extract_text(file: UploadFile = File(...)):
63
+ try:
64
+ image = read_image(await file.read())
65
+ text = process_image(image)
66
+ return JSONResponse(content={"text": text}, status_code=200)
67
+ except Exception as e:
68
+ return JSONResponse(content={"error": str(e)}, status_code=500)
69
+
70
+ @app.post("/extract-text/bs64")
71
+ async def extract_text_bs64(base64_data: str = Form(None)):
72
+ try:
73
+ image = read_base64_image(base64_data)
74
+ text = process_image(image)
75
+ return JSONResponse(content={"text": text}, status_code=200)
76
+ except Exception as e:
77
+ return JSONResponse(content={"error": str(e)}, status_code=500)
src/model/captcha/config.json ADDED
@@ -0,0 +1,177 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "_name_or_path": "microsoft/trocr-small-printed",
3
+ "architectures": [
4
+ "VisionEncoderDecoderModel"
5
+ ],
6
+ "decoder": {
7
+ "_name_or_path": "",
8
+ "activation_dropout": 0.0,
9
+ "activation_function": "relu",
10
+ "add_cross_attention": true,
11
+ "architectures": null,
12
+ "attention_dropout": 0.0,
13
+ "bad_words_ids": null,
14
+ "begin_suppress_tokens": null,
15
+ "bos_token_id": 0,
16
+ "chunk_size_feed_forward": 0,
17
+ "classifier_dropout": 0.0,
18
+ "cross_attention_hidden_size": 384,
19
+ "d_model": 256,
20
+ "decoder_attention_heads": 8,
21
+ "decoder_ffn_dim": 1024,
22
+ "decoder_layerdrop": 0.0,
23
+ "decoder_layers": 6,
24
+ "decoder_start_token_id": 2,
25
+ "diversity_penalty": 0.0,
26
+ "do_sample": false,
27
+ "dropout": 0.1,
28
+ "early_stopping": false,
29
+ "encoder_no_repeat_ngram_size": 0,
30
+ "eos_token_id": 2,
31
+ "exponential_decay_length_penalty": null,
32
+ "finetuning_task": null,
33
+ "forced_bos_token_id": null,
34
+ "forced_eos_token_id": null,
35
+ "id2label": {
36
+ "0": "LABEL_0",
37
+ "1": "LABEL_1"
38
+ },
39
+ "init_std": 0.02,
40
+ "is_decoder": true,
41
+ "is_encoder_decoder": false,
42
+ "label2id": {
43
+ "LABEL_0": 0,
44
+ "LABEL_1": 1
45
+ },
46
+ "layernorm_embedding": true,
47
+ "length_penalty": 1.0,
48
+ "max_length": 20,
49
+ "max_position_embeddings": 512,
50
+ "min_length": 0,
51
+ "model_type": "trocr",
52
+ "no_repeat_ngram_size": 0,
53
+ "num_beam_groups": 1,
54
+ "num_beams": 1,
55
+ "num_return_sequences": 1,
56
+ "output_attentions": false,
57
+ "output_hidden_states": false,
58
+ "output_scores": false,
59
+ "pad_token_id": 1,
60
+ "prefix": null,
61
+ "problem_type": null,
62
+ "pruned_heads": {},
63
+ "remove_invalid_values": false,
64
+ "repetition_penalty": 1.0,
65
+ "return_dict": true,
66
+ "return_dict_in_generate": false,
67
+ "scale_embedding": true,
68
+ "sep_token_id": null,
69
+ "suppress_tokens": null,
70
+ "task_specific_params": null,
71
+ "temperature": 1.0,
72
+ "tf_legacy_loss": false,
73
+ "tie_encoder_decoder": false,
74
+ "tie_word_embeddings": false,
75
+ "tokenizer_class": null,
76
+ "top_k": 50,
77
+ "top_p": 1.0,
78
+ "torch_dtype": null,
79
+ "torchscript": false,
80
+ "typical_p": 1.0,
81
+ "use_bfloat16": false,
82
+ "use_cache": false,
83
+ "use_learned_position_embeddings": true,
84
+ "vocab_size": 64044
85
+ },
86
+ "decoder_start_token_id": 0,
87
+ "early_stopping": true,
88
+ "encoder": {
89
+ "_name_or_path": "",
90
+ "add_cross_attention": false,
91
+ "architectures": null,
92
+ "attention_probs_dropout_prob": 0.0,
93
+ "bad_words_ids": null,
94
+ "begin_suppress_tokens": null,
95
+ "bos_token_id": null,
96
+ "chunk_size_feed_forward": 0,
97
+ "cross_attention_hidden_size": null,
98
+ "decoder_start_token_id": null,
99
+ "diversity_penalty": 0.0,
100
+ "do_sample": false,
101
+ "early_stopping": false,
102
+ "encoder_no_repeat_ngram_size": 0,
103
+ "encoder_stride": 16,
104
+ "eos_token_id": null,
105
+ "exponential_decay_length_penalty": null,
106
+ "finetuning_task": null,
107
+ "forced_bos_token_id": null,
108
+ "forced_eos_token_id": null,
109
+ "hidden_act": "gelu",
110
+ "hidden_dropout_prob": 0.0,
111
+ "hidden_size": 384,
112
+ "id2label": {
113
+ "0": "LABEL_0",
114
+ "1": "LABEL_1"
115
+ },
116
+ "image_size": 384,
117
+ "initializer_range": 0.02,
118
+ "intermediate_size": 1536,
119
+ "is_decoder": false,
120
+ "is_encoder_decoder": false,
121
+ "label2id": {
122
+ "LABEL_0": 0,
123
+ "LABEL_1": 1
124
+ },
125
+ "layer_norm_eps": 1e-12,
126
+ "length_penalty": 1.0,
127
+ "max_length": 20,
128
+ "min_length": 0,
129
+ "model_type": "deit",
130
+ "no_repeat_ngram_size": 0,
131
+ "num_attention_heads": 6,
132
+ "num_beam_groups": 1,
133
+ "num_beams": 1,
134
+ "num_channels": 3,
135
+ "num_hidden_layers": 12,
136
+ "num_return_sequences": 1,
137
+ "output_attentions": false,
138
+ "output_hidden_states": false,
139
+ "output_scores": false,
140
+ "pad_token_id": null,
141
+ "patch_size": 16,
142
+ "prefix": null,
143
+ "problem_type": null,
144
+ "pruned_heads": {},
145
+ "qkv_bias": true,
146
+ "remove_invalid_values": false,
147
+ "repetition_penalty": 1.0,
148
+ "return_dict": true,
149
+ "return_dict_in_generate": false,
150
+ "sep_token_id": null,
151
+ "suppress_tokens": null,
152
+ "task_specific_params": null,
153
+ "temperature": 1.0,
154
+ "tf_legacy_loss": false,
155
+ "tie_encoder_decoder": false,
156
+ "tie_word_embeddings": true,
157
+ "tokenizer_class": null,
158
+ "top_k": 50,
159
+ "top_p": 1.0,
160
+ "torch_dtype": null,
161
+ "torchscript": false,
162
+ "typical_p": 1.0,
163
+ "use_bfloat16": false
164
+ },
165
+ "eos_token_id": 2,
166
+ "is_encoder_decoder": true,
167
+ "length_penalty": 2.0,
168
+ "max_length": 64,
169
+ "model_type": "vision-encoder-decoder",
170
+ "no_repeat_ngram_size": 3,
171
+ "num_beams": 4,
172
+ "pad_token_id": 1,
173
+ "tie_word_embeddings": false,
174
+ "torch_dtype": "float32",
175
+ "transformers_version": "4.35.0",
176
+ "vocab_size": 64044
177
+ }
src/model/captcha/generation_config.json ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "_from_model_config": true,
3
+ "bos_token_id": 0,
4
+ "decoder_start_token_id": 0,
5
+ "early_stopping": true,
6
+ "eos_token_id": 2,
7
+ "length_penalty": 2.0,
8
+ "max_length": 64,
9
+ "no_repeat_ngram_size": 3,
10
+ "num_beams": 4,
11
+ "pad_token_id": 1,
12
+ "transformers_version": "4.35.0",
13
+ "use_cache": false
14
+ }
src/model/captcha/model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:322e7adf1ff7d3b8d38fb7f0a1dc62834523e773a9828cd3b7b79342b91cc2d5
3
+ size 246430696
test_index.http ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Test your FastAPI endpoints
2
+
3
+ GET http://127.0.0.1:8000/
4
+ Accept: application/json
5
+
6
+ ###
7
+
8
+ GET http://127.0.0.1:8000/hello/User
9
+ Accept: application/json
10
+
11
+ ###
12
+
13
+ POST /hello HTTP/1.1
14
+ Host: 127.0.0.1:8000
15
+ Content-Type: application/json
16
+ Content-Length: 28
17
+
18
+ {
19
+ "message": "Fulano!"
20
+ }
test_index.py ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pytest
2
+
3
+ from src.dtos.ISayHelloDto import ISayHelloDto
4
+ from src.index import root, say_hello, hello_message
5
+
6
+
7
+ @pytest.mark.asyncio
8
+ async def test_root():
9
+ result = await root()
10
+ assert result == {'message': 'Hello World'}
11
+
12
+
13
+ @pytest.mark.asyncio
14
+ async def test_say_hello():
15
+ result = await say_hello("John")
16
+ assert result == {'message': 'Hello John'}
17
+
18
+
19
+ @pytest.mark.asyncio
20
+ async def test_hello_message():
21
+ dto = ISayHelloDto(message="Alice")
22
+ result = await hello_message(dto)
23
+ assert result == {'message': 'Hello Alice'}