Skip to content

Commit 7cca46c

Browse files
authored
Merging Dev branch into Main (#22)
# PR: Merging Dev branch into Main ## What has been done? - #18 - #19 - #20 - #21
2 parents 5517cd5 + 0d72a8d commit 7cca46c

9 files changed

Lines changed: 155 additions & 71 deletions

File tree

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy
2+
# More GitHub Actions for Azure: https://github.com/Azure/actions
3+
# More info on Python, GitHub Actions, and Azure App Service: https://aka.ms/python-webapps-actions
4+
5+
name: Build and deploy Python app to Azure Web App - Rose-TT-API
6+
7+
on:
8+
push:
9+
branches:
10+
- dev
11+
workflow_dispatch:
12+
13+
jobs:
14+
build:
15+
runs-on: ubuntu-latest
16+
17+
steps:
18+
- uses: actions/checkout@v4
19+
20+
- name: Set up Python version
21+
uses: actions/setup-python@v1
22+
with:
23+
python-version: '3.12'
24+
25+
- name: Create and start virtual environment
26+
run: |
27+
python -m venv venv
28+
source venv/bin/activate
29+
30+
- name: Install dependencies
31+
run: pip install -r requirements.txt
32+
33+
# Optional: Add step to run tests here (PyTest, Django test suites, etc.)
34+
35+
- name: Zip artifact for deployment
36+
run: zip release.zip ./* -r
37+
38+
- name: Upload artifact for deployment jobs
39+
uses: actions/upload-artifact@v3
40+
with:
41+
name: python-app
42+
path: |
43+
release.zip
44+
!venv/
45+
46+
deploy:
47+
runs-on: ubuntu-latest
48+
needs: build
49+
environment:
50+
name: 'Production'
51+
url: ${{ steps.deploy-to-webapp.outputs.webapp-url }}
52+
permissions:
53+
id-token: write #This is required for requesting the JWT
54+
55+
steps:
56+
- name: Download artifact from build job
57+
uses: actions/download-artifact@v3
58+
with:
59+
name: python-app
60+
61+
- name: Unzip artifact for deployment
62+
run: unzip release.zip
63+
64+
65+
- name: Login to Azure
66+
uses: azure/login@v1
67+
with:
68+
client-id: ${{ secrets.AZUREAPPSERVICE_CLIENTID_036307703B564B82AF74B71826757E2C }}
69+
tenant-id: ${{ secrets.AZUREAPPSERVICE_TENANTID_22210C8B765F49FD80C76EBC938F73DD }}
70+
subscription-id: ${{ secrets.AZUREAPPSERVICE_SUBSCRIPTIONID_B22146082A7841569867B644CE6A4B1E }}
71+
72+
- name: 'Deploy to Azure Web App'
73+
uses: azure/webapps-deploy@v2
74+
id: deploy-to-webapp
75+
with:
76+
app-name: 'Rose-TT-API'
77+
slot-name: 'Production'
78+

app.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
from flask import Flask
22
from grammatical_analysis.grammatical_analysis_controller import grammatical_analysis_api
3+
from dotenv import load_dotenv
4+
import os
35

46
app = Flask(__name__)
57

8+
if os.path.exists('.env'):
9+
load_dotenv()
10+
611
app.register_blueprint(grammatical_analysis_api, url_prefix='/grammatical_analysis')
712

813
if __name__ == '__main__':
9-
app.run(debug=True)
14+
app.run(debug=True)
Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
1-
from flask import Blueprint, jsonify
1+
from flask import Blueprint, jsonify, Response
22
from .grammatical_analysis_service import GrammaticalAnalysisService
3+
from .natural_language_processing_tools.text_preprocessing.tokenizer.Tokenizer_nltk import TokenizerNltk
4+
from .natural_language_processing_tools.text_preprocessing.pos_tagger.POS_tagger_nltk import POSTaggerNltk
5+
from .natural_language_processing_tools.token_processor.GrammarAnalyzerOpenai import GrammarAnalyzerOpenai
6+
from http import HTTPStatus
7+
38
grammatical_analysis_api = Blueprint('grammatical_analysis_api', __name__)
49

5-
@grammatical_analysis_api.route('/')
6-
def index():
7-
return jsonify("Hello World"), 200
10+
tokenizer = TokenizerNltk()
11+
pos_tagger = POSTaggerNltk()
12+
grammatical_analyzer = GrammarAnalyzerOpenai()
13+
814

915
@grammatical_analysis_api.route('/<text>', methods=['GET'])
10-
def analyze_grammar(text):
11-
service = GrammaticalAnalysisService()
16+
def analyze_grammar(text: str) -> tuple[Response, int]:
17+
service = GrammaticalAnalysisService(tokenizer, pos_tagger, grammatical_analyzer)
1218
result = service.analyze_text_grammatically(text)
13-
return jsonify(result), 200
19+
return jsonify(result), HTTPStatus.OK
Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
1-
from .natural_language_processing_tools.NLPNltkOpenai import NLPNltkOpenai
1+
from grammatical_analysis.natural_language_processing_tools.text_preprocessing.tokenizer.Tokenizer import Tokenizer
2+
from grammatical_analysis.natural_language_processing_tools.text_preprocessing.pos_tagger.POSTagger import POSTagger
3+
from grammatical_analysis.natural_language_processing_tools.token_processor.GrammarAnalyzer import GrammarAnalyzer
24

35

46
class GrammaticalAnalysisService:
5-
def __init__(self):
6-
self.nlp = NLPNltkOpenai()
7+
def __init__(self, tokenizer: Tokenizer, pos_tagger: POSTagger, grammar_analyzer: GrammarAnalyzer):
8+
self.tokenizer = tokenizer
9+
self.pos_tagger = pos_tagger
10+
self.grammar_analyzer = grammar_analyzer
711

8-
def analyze_text_grammatically(self, text_to_analyze):
9-
tokenized_sentences = self.nlp.tokenize_sentences(text_to_analyze)
10-
pos_tagged_sentences = self.nlp.tag_sentences_with_pos(tokenized_sentences)
11-
analyzed_text = self.nlp.analyze_grammar(pos_tagged_sentences)
12+
def analyze_text_grammatically(self, text_to_analyze: str) -> str:
13+
tokenized_sentences = self.tokenizer.tokenize_text_by_sentences(text_to_analyze)
14+
pos_tagged_sentences = self.pos_tagger.tag_sentences_with_pos(tokenized_sentences)
15+
analyzed_text = self.grammar_analyzer.analyze_grammar(pos_tagged_sentences)
1216
return analyzed_text

grammatical_analysis/natural_language_processing_tools/NLP.py

Lines changed: 0 additions & 15 deletions
This file was deleted.

grammatical_analysis/natural_language_processing_tools/NLPNltkOpenai.py

Lines changed: 0 additions & 24 deletions
This file was deleted.

grammatical_analysis/natural_language_processing_tools/text_preprocessing/pos_tagger/POS_tagger_nltk.py

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
from .POSTagger import POSTagger
22
import nltk
3+
from nltk import UnigramTagger
34
from nltk.corpus import cess_esp
45

56

6-
def get_tagger():
7+
def get_tagger() -> UnigramTagger:
78
patterns = [
89
(r".*é$", "VBD"), # past verb
910
(r".*ó$", "VBD"), # past verb
@@ -36,11 +37,40 @@ class POSTaggerNltk(POSTagger):
3637
def __init__(self):
3738
nltk.download('cess_esp')
3839
nltk.download('universal_tagset')
39-
40+
4041
def tag_sentences_with_pos(self, tokenized_sentences: list) -> list:
41-
unigram_tagger = get_tagger()
42+
unigram_tagger = self.get_tagger()
4243
tagged_sentences = [
4344
unigram_tagger.tag(nltk.word_tokenize(sentence))
4445
for sentence in tokenized_sentences
4546
]
4647
return tagged_sentences
48+
49+
@staticmethod
50+
def get_tagger() -> nltk.UnigramTagger:
51+
patterns = [
52+
(r".*é$", "VBD"), # past verb
53+
(r".*ó$", "VBD"), # past verb
54+
(r".*rán$", "VBD"), # past verb
55+
(r".*ando$", "VBG"), # gerund
56+
(r".*iendo$", "VBG"), # gerund
57+
(r".*endo$", "VBG"), # gerund
58+
(r".*osa$", "ADJ"), # adjective
59+
(r".*oso$", "ADJ"), # adjective
60+
(r".*o$", "NOUN"), # noun masculine singular
61+
(r".*os$", "NOUN"), # noun masculine plural
62+
(r".*a$", "NOUN"), # noun feminine singular
63+
(r".*as$", "NOUN"), # noun feminine plural
64+
]
65+
66+
default_tagger = "NOUN"
67+
default = nltk.DefaultTagger(default_tagger)
68+
69+
sentences_tagged = []
70+
for sentence in cess_esp.tagged_sents(tagset='universal_tagset'):
71+
sentences_tagged.append([(word, tag) for (word, tag) in sentence])
72+
73+
regex_tagger = nltk.RegexpTagger(patterns, backoff=default)
74+
unigram_tagger = nltk.UnigramTagger(sentences_tagged, backoff=regex_tagger)
75+
76+
return unigram_tagger

grammatical_analysis/natural_language_processing_tools/token_processor/GrammarAnalyzerOpenai.py

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,14 @@
33
import os
44

55

6-
def tagged_sentences_to_string(tagged_sentences):
7-
tagged_sentences_strings = []
8-
for tagged_sentence in tagged_sentences:
9-
sentence_string = " ".join([f"{word}/{tag}" for word, tag in tagged_sentence])
10-
tagged_sentences_strings.append(sentence_string)
11-
return "\n".join(tagged_sentences_strings)
12-
13-
146
class GrammarAnalyzerOpenai(GrammarAnalyzer):
157
def __init__(self):
16-
pass
8+
openai_key = os.environ.get('OPENAI_API_KEY')
9+
self.client = OpenAI(api_key=openai_key)
1710

1811
def analyze_grammar(self, pos_tagged_sentences: list) -> str:
19-
prompt = tagged_sentences_to_string(pos_tagged_sentences)
20-
openai_key = os.environ.get('OPENAI_API_KEY')
21-
client = OpenAI(api_key=openai_key)
22-
completion = client.chat.completions.create(
12+
text_to_analyze = tagged_sentences_to_string(pos_tagged_sentences)
13+
completion = self.client.chat.completions.create(
2314
model="gpt-4",
2415
messages=[
2516
{
@@ -28,11 +19,19 @@ def analyze_grammar(self, pos_tagged_sentences: list) -> str:
2819
},
2920
{
3021
"role": "user",
31-
"content": prompt,
22+
"content": text_to_analyze,
3223
},
3324
],
3425
)
3526

3627
response = completion.choices[0].message.content
3728

3829
return response
30+
31+
@staticmethod
32+
def tagged_sentences_to_string(tagged_sentences):
33+
tagged_sentences_strings = []
34+
for tagged_sentence in tagged_sentences:
35+
sentence_string = " ".join([f"{word}/{tag}" for word, tag in tagged_sentence])
36+
tagged_sentences_strings.append(sentence_string)
37+
return "\n".join(tagged_sentences_strings)

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,4 @@ sniffio==1.3.0
2323
tqdm==4.66.2
2424
typing_extensions==4.9.0
2525
Werkzeug==3.0.1
26+
python-dotenv~=1.0.1

0 commit comments

Comments
 (0)