Skip to content

Commit b605484

Browse files
authored
Fix linter errors and tests (#69)
Fix linter and test errors, update requirements.txt
1 parent 9f270c6 commit b605484

File tree

6 files changed

+196
-95
lines changed

6 files changed

+196
-95
lines changed

.pylintrc

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[MAIN]
2+
3+
ignore=test_pytest.py
4+
5+
[FORMAT]
6+
7+
# Maximum number of characters on a single line.
8+
max-line-length=1000

app.py

+125-41
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
"""
22
Flask Application for Resume Management
33
"""
4-
54
import os
65
import logging
6+
7+
from spellchecker import SpellChecker
8+
from flask_cors import CORS
9+
710
from werkzeug.utils import secure_filename
811
from flask import Flask, jsonify, request, send_from_directory
912
from models import Experience, Education, Skill, UserInformation
1013
from helpers import validate_fields, validate_phone_number, load_data, save_data, generate_id
11-
from spellchecker import SpellChecker
12-
from flask_cors import CORS
14+
1315

1416
spell = SpellChecker()
1517

@@ -58,8 +60,10 @@ def reset_data():
5860
UserInformation("Joe Smith", "[email protected]", "+11234567890"),
5961
]
6062

63+
6164
#reset_data()
6265

66+
6367
def allowed_file(filename):
6468
"""
6569
Check if the uploaded file has an allowed extension.
@@ -69,6 +73,7 @@ def allowed_file(filename):
6973
"""
7074
return "." in filename and filename.rsplit(".", 1)[1].lower() in ALLOWED_EXTENSIONS
7175

76+
7277
def handle_missing_invalid_fields(request_body, required_fields):
7378
"""
7479
Check for missing and invalid fields in the request body.
@@ -85,20 +90,23 @@ def handle_missing_invalid_fields(request_body, required_fields):
8590
]
8691
return missing_fields, invalid_fields
8792

93+
8894
@app.route("/", strict_slashes=False)
8995
def home():
9096
"""
9197
Returns a welcome message for the app
9298
"""
9399
return "Welcome to MLH 24.FAL.A.2 Orientation API Project!!"
94100

101+
95102
@app.route("/test")
96103
def hello_world():
97104
"""
98105
Returns a JSON test message
99106
"""
100107
return jsonify({"message": "Hello, World!"})
101108

109+
102110
@app.route("/resume/experience", methods=["GET", "POST"])
103111
def experience():
104112
"""
@@ -108,19 +116,36 @@ def experience():
108116
return jsonify([exp.__dict__ for exp in data["experience"]]), 200
109117

110118
if request.method == "POST":
111-
request_body = request.form if request.content_type == "multipart/form-data" else request.get_json()
119+
request_body = (
120+
request.form
121+
if request.content_type == "multipart/form-data"
122+
else request.get_json()
123+
)
112124
if not request_body:
113125
return jsonify({"error": "Request must be JSON or include form data"}), 400
114126

115-
required_fields = {"title": str, "company": str, "start_date": str, "end_date": str, "description": str}
116-
missing_fields, invalid_fields = handle_missing_invalid_fields(request_body, required_fields)
127+
required_fields = {
128+
"title": str,
129+
"company": str,
130+
"start_date": str,
131+
"end_date": str,
132+
"description": str,
133+
}
134+
missing_fields, invalid_fields = handle_missing_invalid_fields(
135+
request_body, required_fields
136+
)
117137

118138
if missing_fields or invalid_fields:
119-
return jsonify({
120-
"error": "Validation failed",
121-
"missing_fields": missing_fields,
122-
"invalid_fields": invalid_fields
123-
}), 400
139+
return (
140+
jsonify(
141+
{
142+
"error": "Validation failed",
143+
"missing_fields": missing_fields,
144+
"invalid_fields": invalid_fields,
145+
}
146+
),
147+
400,
148+
)
124149

125150
# Handle logo file
126151
logo_filename = DEFAULT_LOGO
@@ -130,7 +155,7 @@ def experience():
130155
filename = secure_filename(logo_file.filename)
131156
logo_file.save(os.path.join(app.config["UPLOAD_FOLDER"], filename))
132157
logo_filename = filename
133-
158+
134159
# Create new experience
135160
new_id = generate_id(data, 'experience')
136161

@@ -149,6 +174,9 @@ def experience():
149174
new_experience_index = len(data["experience"]) - 1
150175
return jsonify({"message": "New experience created", "id": new_experience_index}), 201
151176

177+
return 400
178+
179+
152180
@app.route("/resume/experience/<int:index>", methods=["DELETE"])
153181
def delete_experience(index):
154182
"""
@@ -173,16 +201,24 @@ def education():
173201
if not request_body:
174202
return jsonify({"error": "Request must be JSON"}), 400
175203

176-
required_fields = {"course": str, "school": str, "start_date": str, "end_date": str, "grade": str}
177-
missing_fields, invalid_fields = handle_missing_invalid_fields(request_body, required_fields)
204+
required_fields = {
205+
"course": str,
206+
"school": str,
207+
"start_date": str,
208+
"end_date": str,
209+
"grade": str,
210+
}
211+
missing_fields, invalid_fields = handle_missing_invalid_fields(
212+
request_body, required_fields
213+
)
178214

179215
if missing_fields or invalid_fields:
180216
return jsonify({
181217
"error": "Validation failed",
182218
"missing_fields": missing_fields,
183219
"invalid_fields": invalid_fields
184220
}), 400
185-
221+
186222
new_id = generate_id(data, 'education')
187223

188224
# Create new education entry
@@ -200,6 +236,8 @@ def education():
200236
new_education_index = new_id - 1
201237
return jsonify({"message": "New education created", "id": new_education_index}), 201
202238

239+
return 400
240+
203241

204242
@app.route("/resume/experience/<int:index>", methods=["GET"])
205243
def experience_by_index(index):
@@ -220,6 +258,7 @@ def education_by_index(index):
220258
return jsonify(data["education"][index].__dict__), 200
221259
return jsonify({"error": "Education not found"}), 404
222260

261+
223262
@app.route("/resume/education/<int:index>", methods=["DELETE"])
224263
def delete_education(index):
225264
"""
@@ -240,19 +279,30 @@ def skill():
240279
return jsonify([sk.__dict__ for sk in data["skill"]]), 200
241280

242281
if request.method == "POST":
243-
request_body = request.form if request.content_type == "multipart/form-data" else request.get_json()
282+
request_body = (
283+
request.form
284+
if request.content_type == "multipart/form-data"
285+
else request.get_json()
286+
)
244287
if not request_body:
245288
return jsonify({"error": "Request must be JSON or include form data"}), 400
246289

247290
required_fields = {"name": str, "proficiency": str}
248-
missing_fields, invalid_fields = handle_missing_invalid_fields(request_body, required_fields)
291+
missing_fields, invalid_fields = handle_missing_invalid_fields(
292+
request_body, required_fields
293+
)
249294

250295
if missing_fields or invalid_fields:
251-
return jsonify({
252-
"error": "Validation failed",
253-
"missing_fields": missing_fields,
254-
"invalid_fields": invalid_fields
255-
}), 400
296+
return (
297+
jsonify(
298+
{
299+
"error": "Validation failed",
300+
"missing_fields": missing_fields,
301+
"invalid_fields": invalid_fields,
302+
}
303+
),
304+
400,
305+
)
256306

257307
# Handle logo file
258308
logo_filename = DEFAULT_LOGO
@@ -264,11 +314,16 @@ def skill():
264314
logo_filename = filename
265315

266316
# Create new skill
267-
new_skill = Skill(request_body["name"], request_body["proficiency"], logo_filename)
317+
new_skill = Skill(
318+
request_body["name"], request_body["proficiency"], logo_filename
319+
)
268320
data["skill"].append(new_skill)
321+
269322
save_data('data/data.json', data)
270323
return jsonify({"message": "New skill created", "id": len(data["skill"]) - 1}), 201
271324

325+
return 400
326+
272327

273328
@app.route("/resume/user_information", methods=["GET", "POST", "PUT"])
274329
def user_information():
@@ -290,6 +345,9 @@ def user_information():
290345
data["user_information"] = request.json
291346
return jsonify(data["user_information"]), 201
292347

348+
return 400
349+
350+
293351
@app.route("/resume/skill/<int:index>", methods=["DELETE"])
294352
def delete_skill(index):
295353
"""
@@ -303,10 +361,12 @@ def delete_skill(index):
303361
return jsonify({"error": "Skill not found"}), 404
304362

305363

306-
307-
308364
@app.route("/resume/spellcheck", methods=["POST"])
309365
def spellcheck():
366+
"""
367+
Spellcheck the resume.
368+
(TODO add more detailed info here)
369+
"""
310370
request_body = request.get_json()
311371
if not request_body:
312372
return jsonify({"error": "Request must be JSON"}), 400
@@ -317,34 +377,55 @@ def spellcheck():
317377
title = exp.get("title", "")
318378
description = exp.get("description", "")
319379
if title:
320-
results.append({
321-
"before": title,
322-
"after": list(spell.candidates(title)) if spell.candidates(title) else []
323-
})
380+
results.append(
381+
{
382+
"before": title,
383+
"after": (
384+
list(spell.candidates(title)) if spell.candidates(title) else []
385+
),
386+
}
387+
)
324388
if description:
325-
results.append({
326-
"before": description,
327-
"after": list(spell.candidates(description)) if spell.candidates(description) else []
328-
})
389+
results.append(
390+
{
391+
"before": description,
392+
"after": (
393+
list(spell.candidates(description))
394+
if spell.candidates(description)
395+
else []
396+
),
397+
}
398+
)
329399

330400
for edu in request_body.get("education", []):
331401
course = edu.get("course", "")
332402
if course:
333-
results.append({
334-
"before": course,
335-
"after": list(spell.candidates(course)) if spell.candidates(course) else []
336-
})
403+
results.append(
404+
{
405+
"before": course,
406+
"after": (
407+
list(spell.candidates(course))
408+
if spell.candidates(course)
409+
else []
410+
),
411+
}
412+
)
337413

338414
for sk in request_body.get("skill", []):
339415
name = sk.get("name", "")
340416
if name:
341-
results.append({
342-
"before": name,
343-
"after": list(spell.candidates(name)) if spell.candidates(name) else []
344-
})
417+
results.append(
418+
{
419+
"before": name,
420+
"after": (
421+
list(spell.candidates(name)) if spell.candidates(name) else []
422+
),
423+
}
424+
)
345425

346426
return jsonify(results), 200
347427

428+
348429
@app.route("/custom-section", methods=["POST"])
349430
def add_custom_section():
350431
"""
@@ -368,18 +449,21 @@ def add_custom_section():
368449
logging.info("New custom section added: %s", title)
369450
return jsonify({"message": "Custom section added", "id": section_id}), 201
370451

452+
371453
@app.route("/custom-sections", methods=["GET"])
372454
def get_custom_sections():
373455
"""
374456
Retrieve all custom sections added by the user.
375457
"""
376458
return jsonify(data["custom_sections"]), 200
377459

460+
378461
if __name__ == "__main__":
379462
if not os.path.exists(UPLOAD_FOLDER):
380463
os.makedirs(UPLOAD_FOLDER)
381464
app.run(debug=True)
382465

466+
383467
@app.route("/uploads/<path:filename>")
384468
def uploaded_file(filename):
385469
"""

0 commit comments

Comments
 (0)