Skip to content

Python ai backend#3

Open
chirayukale2006-gif wants to merge 4 commits intomainfrom
python-ai-backend
Open

Python ai backend#3
chirayukale2006-gif wants to merge 4 commits intomainfrom
python-ai-backend

Conversation

@chirayukale2006-gif
Copy link
Copy Markdown
Collaborator

@chirayukale2006-gif chirayukale2006-gif commented Apr 12, 2026

Title:
Add Python AI services

Description:

What I built

  • ✅ Symptom Checker API

Summary by CodeRabbit

  • New Features

    • Added a symptom-checking API endpoint that accepts user messages and returns AI-generated replies
    • Persisted per-session chat history with automatic retention limits
    • Exposed a simple health/ready response for the API and enabled cross-origin requests
  • Chores

    • Added environment configuration template and service dependency list; ignored local dev artifacts

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 12, 2026

📝 Walkthrough
🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title "Python ai backend" is vague and generic; it lacks specific focus on the main change (implementing a symptom checker API with Flask, MongoDB, and Groq integration). Use a more descriptive title that highlights the primary feature, such as "Add symptom checker API with Flask, MongoDB, and Groq integration" or "Implement pet symptom checker backend service".
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch python-ai-backend

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🧹 Nitpick comments (4)
services/requirements.txt (1)

1-7: Pin dependency versions (or use a lock file) for reproducible deployments.

Floating versions here make builds nondeterministic and risk surprise breakage during installs.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@services/requirements.txt` around lines 1 - 7, services/requirements.txt
currently lists unpinned packages (flask, flask-cors, groq, pymongo,
python-dotenv, certifi, dnspython); update this to use exact versions (e.g.,
package==x.y.z) or add a generated lock file (pip-tools/poetry/poetry.lock) and
commit it so installs are reproducible. Modify the requirements file to pin each
package to a tested version or switch to a lockfile workflow and update
CI/install docs to use that lockfile when installing.
services/app.py (1)

8-8: Consider restricting CORS origins instead of allowing all by default.

CORS(app) with defaults is broad; an explicit allowlist is safer for production.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@services/app.py` at line 8, Replace the open CORS(app) call with a restricted
origin allowlist: update the CORS initialization where CORS(app) is called to
explicitly pass allowed origins (e.g., using the origins or resources argument
of flask_cors.CORS) and load those origins from configuration or an environment
variable; specifically modify the CORS(app) invocation in services/app.py to
something like CORS(app, origins=app.config['CORS_ORIGINS'] or a parsed env var)
so only the intended domains are permitted instead of allowing all origins.
services/services/chat_service.py (1)

35-45: Optimize retention cleanup with index + bulk delete.

Current trim logic does multiple delete round-trips and depends on repeated scans. Add a compound index and batch deletes for better performance under load.

🔧 Suggested refactor
-    count=collection.count_documents({"session_id":session_id, "user_id":user_id})
+    collection.create_index([("session_id", 1), ("user_id", 1), ("created_at", 1)])
+    count=collection.count_documents({"session_id":session_id, "user_id":user_id})
     if count>20:
         lim =count-20
         old=collection.find({
             "session_id":session_id, "user_id":user_id},
             sort=[("created_at",1)],
             limit=lim)
-        
-        for d in old:
-            collection.delete_one({"_id":d["_id"]})
+        old_ids = [d["_id"] for d in old]
+        if old_ids:
+            collection.delete_many({"_id": {"$in": old_ids}})
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@services/services/chat_service.py` around lines 35 - 45, Add a compound index
and replace per-document deletes with batched deletes: create a compound index
on collection via
collection.create_index([("session_id",1),("user_id",1),("created_at",1)]) to
speed the query, then when count_documents(...) > 20 fetch the oldest IDs with
collection.find({"session_id": session_id, "user_id": user_id},
projection={"_id":1}, sort=[("created_at",1)], limit=lim) and call
collection.delete_many({"_id": {"$in": ids}}) (split into reasonable batch sizes
if lim can be large) instead of looping over delete_one; keep the same
session_id/user_id filters and use count_documents, find, and delete_many as
shown.
services/config/db.py (1)

9-24: Remove commented debug/experiment blocks from the DB module.

Keeping large commented-out data access snippets in production paths adds noise and makes maintenance harder.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@services/config/db.py` around lines 9 - 24, Remove the large commented-out DB
debug/experiment block and leave only the functional data-access code: delete
the commented lines that reference db, collection, print/debug statements and
any commented delete/find loops, keeping the real insert operation around
collection.insert_one({...}) (or refactor that insert into a clear helper
function like save_chat_history if present). Ensure variables referenced
(collection, db, session_id, user_id, role, content, datetime) remain used or
imported so no unused symbol warnings occur; if the insert was for testing only,
move the test snippet to a dedicated test or dev script rather than leaving it
commented in services/config/db.py.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@services/.env.example`:
- Around line 1-2: The env var names in the template (GROQ_API_KEY, MONGO_URI)
don't match the runtime lookups (groq_key, url); update the code to use a single
naming scheme—prefer the uppercase names from the template. Replace any uses of
groq_key with GROQ_API_KEY and url with MONGO_URI in the runtime code (e.g., in
the DB connector in config/db.py and the consumer in controllers/symptoms.py) so
os.getenv()/process.env lookups use the same keys as .env.example, and ensure
any error messages or defaults reference the same variable names.

In `@services/app.py`:
- Around line 18-19: The startup block is hardcoding debug=True which exposes
internals; update the if __name__=="__main__": app.run(...) invocation to read
the debug flag from an environment variable (e.g., FLASK_DEBUG or an application
config flag) and convert it to a boolean before passing it to app.run, or omit
debug entirely in production. Locate the main entry (the if __name__=="__main__"
block and the app.run call) and replace the literal True with a value derived
from os.environ (or app.config) so debug mode is controlled by configuration
rather than hardcoded.

In `@services/config/db.py`:
- Around line 5-8: Replace the use of os.getenv("url") with the documented
MONGO_URI environment variable and validate it before creating the MongoClient:
call load_dotenv(), read mongo_uri = os.getenv("MONGO_URI"), check that
mongo_uri is a non-empty string and raise a clear runtime error (or log and
exit) if missing, then pass mongo_uri into MongoClient instead of url; update
the symbols referenced (os.getenv("url") -> os.getenv("MONGO_URI"),
MongoClient(url) -> MongoClient(mongo_uri)) to ensure fail-fast behavior with a
clear message.

In `@services/controllers/symptoms.py`:
- Around line 30-33: The call to client.chat.completions.create in
check_symptoms is unhandled and can raise groq.APIError, timeouts, or network
exceptions; wrap the call in a try/except around
client.chat.completions.create(...) inside check_symptoms, catch groq.APIError
and relevant network/timeout exceptions (e.g.,
requests.exceptions.RequestException or socket.timeout depending on HTTP
client), log the exception, and return a graceful error response (HTTP 502/503
with a JSON error message) instead of letting the exception propagate.
- Around line 7-9: The Groq client is being initialized using
os.getenv("groq_key") which doesn't match the .env.example's GROQ_API_KEY;
update the Groq client initialization (the client=Groq(...) call) to use
os.getenv("GROQ_API_KEY") and add a startup validation after load_dotenv() that
checks the env value (e.g., groq_key or groq_api_key variable) and logs a clear
error and exits (or raises) if it's missing so the app fails fast instead of
failing silently at API call time.

In `@services/routes/symptoms_route.py`:
- Around line 13-14: Wrap the external call to check_symptoms in the
symptoms_route handler with a try/except that catches
network/HTTP/auth/rate-limit errors from the Groq client and returns structured
JSON responses with appropriate status codes; for transient/unavailable service
errors return a 502 with a message, for rate-limit errors return a 503 (or
inspect the exception for 429 and return 429), and for unexpected exceptions
return a 500—include the error message in the JSON body for debugging and ensure
you still return via jsonify({"reply": ...}) or jsonify({"error": ...}), using
the Flask response tuple (body, status_code) to set the HTTP status.
- Around line 7-13: Guard against non-JSON payloads by first obtaining the body
safely (use request.get_json(silent=True) or check request.is_json) and handle
None before accessing .get(); validate that s_id, u_id, and msg are present and
non-empty, and if any are missing return jsonify({"error": "missing fields",
"missing": [...]}) with a 400 status code instead of 200; finally pass the
validated s_id, u_id, msg into check_symptoms and keep using jsonify for the
success response. Ensure you update references to data, s_id, u_id, and msg in
this route so no .get() is called on None and that validation failures return
HTTP 400.

---

Nitpick comments:
In `@services/app.py`:
- Line 8: Replace the open CORS(app) call with a restricted origin allowlist:
update the CORS initialization where CORS(app) is called to explicitly pass
allowed origins (e.g., using the origins or resources argument of
flask_cors.CORS) and load those origins from configuration or an environment
variable; specifically modify the CORS(app) invocation in services/app.py to
something like CORS(app, origins=app.config['CORS_ORIGINS'] or a parsed env var)
so only the intended domains are permitted instead of allowing all origins.

In `@services/config/db.py`:
- Around line 9-24: Remove the large commented-out DB debug/experiment block and
leave only the functional data-access code: delete the commented lines that
reference db, collection, print/debug statements and any commented delete/find
loops, keeping the real insert operation around collection.insert_one({...}) (or
refactor that insert into a clear helper function like save_chat_history if
present). Ensure variables referenced (collection, db, session_id, user_id,
role, content, datetime) remain used or imported so no unused symbol warnings
occur; if the insert was for testing only, move the test snippet to a dedicated
test or dev script rather than leaving it commented in services/config/db.py.

In `@services/requirements.txt`:
- Around line 1-7: services/requirements.txt currently lists unpinned packages
(flask, flask-cors, groq, pymongo, python-dotenv, certifi, dnspython); update
this to use exact versions (e.g., package==x.y.z) or add a generated lock file
(pip-tools/poetry/poetry.lock) and commit it so installs are reproducible.
Modify the requirements file to pin each package to a tested version or switch
to a lockfile workflow and update CI/install docs to use that lockfile when
installing.

In `@services/services/chat_service.py`:
- Around line 35-45: Add a compound index and replace per-document deletes with
batched deletes: create a compound index on collection via
collection.create_index([("session_id",1),("user_id",1),("created_at",1)]) to
speed the query, then when count_documents(...) > 20 fetch the oldest IDs with
collection.find({"session_id": session_id, "user_id": user_id},
projection={"_id":1}, sort=[("created_at",1)], limit=lim) and call
collection.delete_many({"_id": {"$in": ids}}) (split into reasonable batch sizes
if lim can be large) instead of looping over delete_one; keep the same
session_id/user_id filters and use count_documents, find, and delete_many as
shown.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 714f678d-44f7-467a-be79-060c798b575e

📥 Commits

Reviewing files that changed from the base of the PR and between 1f7d564 and 93df08d.

📒 Files selected for processing (11)
  • services/.env.example
  • services/.gitignore
  • services/__init__.py
  • services/app.py
  • services/config/__init__.py
  • services/config/db.py
  • services/controllers/symptoms.py
  • services/requirements.txt
  • services/routes/symptoms_route.py
  • services/services/__init__.py
  • services/services/chat_service.py

Comment thread services/.env.example
Comment on lines +1 to +2
GROQ_API_KEY=your_groq_key_here
MONGO_URI=your_mongodb_uri_here No newline at end of file
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Environment variable names are inconsistent with runtime lookups.

services/.env.example uses GROQ_API_KEY / MONGO_URI, but runtime currently reads different keys (groq_key and url). A clean setup using this template will fail to authenticate/connect.

Please standardize one naming scheme across services/.env.example, services/config/db.py (Line [6]), and services/controllers/symptoms.py (Line [8]).

🧰 Tools
🪛 dotenv-linter (4.0.0)

[warning] 2-2: [EndingBlankLine] No blank line at the end of the file

(EndingBlankLine)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@services/.env.example` around lines 1 - 2, The env var names in the template
(GROQ_API_KEY, MONGO_URI) don't match the runtime lookups (groq_key, url);
update the code to use a single naming scheme—prefer the uppercase names from
the template. Replace any uses of groq_key with GROQ_API_KEY and url with
MONGO_URI in the runtime code (e.g., in the DB connector in config/db.py and the
consumer in controllers/symptoms.py) so os.getenv()/process.env lookups use the
same keys as .env.example, and ensure any error messages or defaults reference
the same variable names.

Comment thread services/app.py
Comment on lines +18 to +19
if __name__=="__main__":
app.run(debug=True, port=5000)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check if the file exists and examine the content around lines 18-19
if [ -f "services/app.py" ]; then
  echo "=== services/app.py content (lines 1-30) ==="
  head -30 "services/app.py" | cat -n
else
  echo "File services/app.py not found. Searching for app.py files..."
  find . -name "app.py" -type f
fi

Repository: call-0f-code/Pets-Platform

Length of output: 709


🏁 Script executed:

#!/bin/bash
# Check for any existing environment-based Flask configuration
rg "FLASK_DEBUG|FLASK_ENV|os\.getenv|os\.environ" --type py

Repository: call-0f-code/Pets-Platform

Length of output: 263


Do not hardcode debug=True in runtime startup.

Flask debug mode enabled at line 19 exposes sensitive internals through detailed error pages and the interactive debugger. Use environment variables to control this setting.

🔧 Suggested fix
+import os
+
 if __name__=="__main__":
-    app.run(debug=True, port=5000)
+    app.run(
+        debug=os.getenv("FLASK_DEBUG", "0") == "1",
+        port=int(os.getenv("PORT", "5000")),
+    )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if __name__=="__main__":
app.run(debug=True, port=5000)
import os
if __name__=="__main__":
app.run(
debug=os.getenv("FLASK_DEBUG", "0") == "1",
port=int(os.getenv("PORT", "5000")),
)
🧰 Tools
🪛 ast-grep (0.42.1)

[warning] 18-18: Detected Flask app with debug=True. Do not deploy to production with this flag enabled as it will leak sensitive information. Instead, consider using Flask configuration variables or setting 'debug' using system environment variables.
Context: app.run(debug=True, port=5000)
Note: [CWE-489] Active Debug Code. [REFERENCES]
- https://labs.detectify.com/2015/10/02/how-patreon-got-hacked-publicly-exposed-werkzeug-debugger/

(debug-enabled-python)

🪛 Ruff (0.15.10)

[error] 19-19: Use of debug=True in Flask app detected

(S201)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@services/app.py` around lines 18 - 19, The startup block is hardcoding
debug=True which exposes internals; update the if __name__=="__main__":
app.run(...) invocation to read the debug flag from an environment variable
(e.g., FLASK_DEBUG or an application config flag) and convert it to a boolean
before passing it to app.run, or omit debug entirely in production. Locate the
main entry (the if __name__=="__main__" block and the app.run call) and replace
the literal True with a value derived from os.environ (or app.config) so debug
mode is controlled by configuration rather than hardcoded.

Comment thread services/config/db.py
Comment on lines +5 to +8
load_dotenv()
url=os.getenv("url")

client=MongoClient(url)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

git ls-files | head -20

Repository: call-0f-code/Pets-Platform

Length of output: 603


🏁 Script executed:

# Find the specific file mentioned
find . -name "db.py" -path "*/config/*" 2>/dev/null

Repository: call-0f-code/Pets-Platform

Length of output: 93


🏁 Script executed:

# Check repository structure
ls -la

Repository: call-0f-code/Pets-Platform

Length of output: 466


🏁 Script executed:

# Read the file in question
cat -n services/config/db.py

Repository: call-0f-code/Pets-Platform

Length of output: 871


🏁 Script executed:

# Search for MONGO_URI references in the codebase
rg "MONGO_URI" --type py

Repository: call-0f-code/Pets-Platform

Length of output: 52


🏁 Script executed:

# Search for "url" environment variable references
rg 'os\.getenv\("url"\)' --type py

Repository: call-0f-code/Pets-Platform

Length of output: 112


🏁 Script executed:

# Look for environment documentation or .env.example
find . -name ".env*" -o -name "*.md" | head -20

Repository: call-0f-code/Pets-Platform

Length of output: 114


🏁 Script executed:

# Check environment documentation
cat -n ./services/.env.example

Repository: call-0f-code/Pets-Platform

Length of output: 147


🏁 Script executed:

# Search for other references to environment variables and configuration
rg "getenv" --type py

Repository: call-0f-code/Pets-Platform

Length of output: 263


🏁 Script executed:

# Check if there's any documentation about the database configuration
find . -name "README*" -o -name "SETUP*" | xargs grep -l "MONGO\|mongo\|database" 2>/dev/null

Repository: call-0f-code/Pets-Platform

Length of output: 54


Use documented MONGO_URI environment variable and validate before MongoClient initialization.

The code uses os.getenv("url") but .env.example documents MONGO_URI. Additionally, there is no validation—if the environment variable is not set, MongoClient(None) will fail silently or hang. Align with the documented configuration key and fail fast with a clear error message.

🔧 Suggested fix
 load_dotenv()
-url=os.getenv("url")
+mongo_uri = os.getenv("MONGO_URI")
+if not mongo_uri:
+    raise RuntimeError("MONGO_URI is not set")
 
-client=MongoClient(url)
+client = MongoClient(mongo_uri, serverSelectionTimeoutMS=5000)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
load_dotenv()
url=os.getenv("url")
client=MongoClient(url)
load_dotenv()
mongo_uri = os.getenv("MONGO_URI")
if not mongo_uri:
raise RuntimeError("MONGO_URI is not set")
client = MongoClient(mongo_uri, serverSelectionTimeoutMS=5000)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@services/config/db.py` around lines 5 - 8, Replace the use of
os.getenv("url") with the documented MONGO_URI environment variable and validate
it before creating the MongoClient: call load_dotenv(), read mongo_uri =
os.getenv("MONGO_URI"), check that mongo_uri is a non-empty string and raise a
clear runtime error (or log and exit) if missing, then pass mongo_uri into
MongoClient instead of url; update the symbols referenced (os.getenv("url") ->
os.getenv("MONGO_URI"), MongoClient(url) -> MongoClient(mongo_uri)) to ensure
fail-fast behavior with a clear message.

Comment on lines +7 to +9
load_dotenv()
client=Groq(api_key=os.getenv("groq_key"))
# print("API KEY:", os.getenv("api_key"))
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, let's examine the actual code in the symptoms.py file
head -20 services/controllers/symptoms.py

Repository: call-0f-code/Pets-Platform

Length of output: 646


🏁 Script executed:

# Check if .env.example exists and what variables it defines
find . -name ".env.example" -o -name ".env.sample" | head -5

Repository: call-0f-code/Pets-Platform

Length of output: 93


🏁 Script executed:

# Search for groq_key and GROQ_API_KEY usage throughout the codebase
rg "groq_key|GROQ_API_KEY" --no-heading

Repository: call-0f-code/Pets-Platform

Length of output: 145


🏁 Script executed:

# Read the .env.example file to see the recommended key naming
cat services/.env.example

Repository: call-0f-code/Pets-Platform

Length of output: 133


🏁 Script executed:

# Check if there's any validation logic for environment variables elsewhere in the codebase
rg "RuntimeError|ValueError|if not.*getenv" --type py | head -20

Repository: call-0f-code/Pets-Platform

Length of output: 52


🏁 Script executed:

# Check if the Groq client initialization handles missing keys gracefully or fails at runtime
rg "Groq\(" -A 5 -B 2 --type py

Repository: call-0f-code/Pets-Platform

Length of output: 482


Standardize Groq API key environment variable name and add startup validation.

Line 8 uses groq_key, but .env.example defines GROQ_API_KEY. This mismatch causes the client to initialize with api_key=None, failing silently at startup and producing unclear errors only when API calls are made.

Suggested fix
load_dotenv()
-client=Groq(api_key=os.getenv("groq_key"))
+api_key = os.getenv("GROQ_API_KEY")
+if not api_key:
+    raise RuntimeError("GROQ_API_KEY is not set")
+client = Groq(api_key=api_key)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
load_dotenv()
client=Groq(api_key=os.getenv("groq_key"))
# print("API KEY:", os.getenv("api_key"))
load_dotenv()
api_key = os.getenv("GROQ_API_KEY")
if not api_key:
raise RuntimeError("GROQ_API_KEY is not set")
client = Groq(api_key=api_key)
# print("API KEY:", os.getenv("api_key"))
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@services/controllers/symptoms.py` around lines 7 - 9, The Groq client is
being initialized using os.getenv("groq_key") which doesn't match the
.env.example's GROQ_API_KEY; update the Groq client initialization (the
client=Groq(...) call) to use os.getenv("GROQ_API_KEY") and add a startup
validation after load_dotenv() that checks the env value (e.g., groq_key or
groq_api_key variable) and logs a clear error and exits (or raises) if it's
missing so the app fails fast instead of failing silently at API call time.

Comment on lines +30 to +33
responce=client.chat.completions.create(
model="llama-3.3-70b-versatile",
messages=msg
)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find and examine the symptoms.py file
find . -name "symptoms.py" -type f

Repository: call-0f-code/Pets-Platform

Length of output: 104


🏁 Script executed:

#!/bin/bash
# List the file and check its size
ls -la services/controllers/symptoms.py 2>/dev/null || echo "File not found at expected path"
wc -l services/controllers/symptoms.py 2>/dev/null || echo "Cannot read file"

Repository: call-0f-code/Pets-Platform

Length of output: 187


🏁 Script executed:

#!/bin/bash
# Read the file with context around lines 30-33
cat -n services/controllers/symptoms.py | sed -n '15,50p'

Repository: call-0f-code/Pets-Platform

Length of output: 1126


🏁 Script executed:

#!/bin/bash
# Read the complete file to ensure no error handling is missed
cat -n services/controllers/symptoms.py

Repository: call-0f-code/Pets-Platform

Length of output: 1548


🏁 Script executed:

#!/bin/bash
# Search for where check_symptoms is called from and how errors are handled
rg "check_symptoms" --type py -B 3 -A 5

Repository: call-0f-code/Pets-Platform

Length of output: 1520


🏁 Script executed:

#!/bin/bash
# Look for route definitions or Flask app routes
find . -name "*.py" -type f | xargs rg -l "app\.|@.*route|@.*post|@.*get" | head -5

Repository: call-0f-code/Pets-Platform

Length of output: 123


🏁 Script executed:

#!/bin/bash
# Read the complete symptoms_route.py file
cat -n services/routes/symptoms_route.py

Repository: call-0f-code/Pets-Platform

Length of output: 617


🏁 Script executed:

#!/bin/bash
# Check app.py for global error handling or middleware
cat -n services/app.py

Repository: call-0f-code/Pets-Platform

Length of output: 664


Wrap the external API call with error handling.

client.chat.completions.create(...) is a network dependency with no error handling. Groq API failures (timeouts, rate limits, service unavailability) will propagate as unhandled exceptions, causing hard 500 errors without user-friendly messaging. Add a try-except block in check_symptoms() (lines 30-33) to handle groq.APIError, network exceptions, and timeout errors, returning a graceful error response instead.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@services/controllers/symptoms.py` around lines 30 - 33, The call to
client.chat.completions.create in check_symptoms is unhandled and can raise
groq.APIError, timeouts, or network exceptions; wrap the call in a try/except
around client.chat.completions.create(...) inside check_symptoms, catch
groq.APIError and relevant network/timeout exceptions (e.g.,
requests.exceptions.RequestException or socket.timeout depending on HTTP
client), log the exception, and return a graceful error response (HTTP 502/503
with a JSON error message) instead of letting the exception propagate.

Comment on lines +7 to +13
data=request.json
s_id=data.get("session_id")
u_id=data.get("user_id")
msg=data.get("message")
if not msg:
return jsonify({"error": "message required"})
reply=check_symptoms(s_id, u_id, msg)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

fd -t f "symptoms_route.py" -o "**/*symptoms_route*"

Repository: call-0f-code/Pets-Platform

Length of output: 227


🏁 Script executed:

fd -t f symptoms_route.py

Repository: call-0f-code/Pets-Platform

Length of output: 103


🏁 Script executed:

cat -n services/routes/symptoms_route.py

Repository: call-0f-code/Pets-Platform

Length of output: 617


Guard against non-JSON payloads and validate all required fields with proper error status codes.

Line 7 assigns request.json directly, which returns None for invalid or missing JSON payloads. This causes an AttributeError on line 8 when calling .get() on None. Additionally, validation only checks msg but ignores s_id and u_id, and returns HTTP 200 instead of 400 for validation failures.

🔧 Suggested fix
 def ask():
-    data=request.json
+    data = request.get_json(silent=True) or {}
     s_id=data.get("session_id")
     u_id=data.get("user_id")
     msg=data.get("message")
-    if not msg:
-        return jsonify({"error": "message required"})
+    if not s_id or not u_id or not msg:
+        return jsonify({"error": "session_id, user_id and message are required"}), 400
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@services/routes/symptoms_route.py` around lines 7 - 13, Guard against
non-JSON payloads by first obtaining the body safely (use
request.get_json(silent=True) or check request.is_json) and handle None before
accessing .get(); validate that s_id, u_id, and msg are present and non-empty,
and if any are missing return jsonify({"error": "missing fields", "missing":
[...]}) with a 400 status code instead of 200; finally pass the validated s_id,
u_id, msg into check_symptoms and keep using jsonify for the success response.
Ensure you update references to data, s_id, u_id, and msg in this route so no
.get() is called on None and that validation failures return HTTP 400.

Comment on lines +13 to +14
reply=check_symptoms(s_id, u_id, msg)
return jsonify({"reply":reply})
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

find . -type f -name "symptoms_route.py" | head -20

Repository: call-0f-code/Pets-Platform

Length of output: 105


🏁 Script executed:

git ls-files | grep -E "(symptoms|route)" | head -20

Repository: call-0f-code/Pets-Platform

Length of output: 160


🏁 Script executed:

find . -type f -name "*.py" | grep -i route | head -20

Repository: call-0f-code/Pets-Platform

Length of output: 105


🏁 Script executed:

wc -l ./services/routes/symptoms_route.py

Repository: call-0f-code/Pets-Platform

Length of output: 108


🏁 Script executed:

cat -n ./services/routes/symptoms_route.py

Repository: call-0f-code/Pets-Platform

Length of output: 617


🏁 Script executed:

wc -l ./services/controllers/symptoms.py

Repository: call-0f-code/Pets-Platform

Length of output: 107


🏁 Script executed:

cat -n ./services/controllers/symptoms.py

Repository: call-0f-code/Pets-Platform

Length of output: 1548


🏁 Script executed:

find . -type f -name "*.py" -path "*/services/*" | grep -E "(app|main|__init__|server)" | head -20

Repository: call-0f-code/Pets-Platform

Length of output: 172


🏁 Script executed:

rg -t py "errorhandler|error_handler|@app\." --max-count=20

Repository: call-0f-code/Pets-Platform

Length of output: 101


🏁 Script executed:

find . -type f -name "app.py" -o -name "main.py" -o -name "__main__.py"

Repository: call-0f-code/Pets-Platform

Length of output: 87


🏁 Script executed:

wc -l ./services/app.py

Repository: call-0f-code/Pets-Platform

Length of output: 90


🏁 Script executed:

cat -n ./services/app.py

Repository: call-0f-code/Pets-Platform

Length of output: 664


Add error handling for external AI service failures.

The check_symptoms() call makes an external Groq API request that can fail due to network issues, authentication errors, or rate limits. Without error handling, these failures return unstructured 500 responses. Wrap the call in a try-except block and map failures to appropriate HTTP status codes (e.g., 502 for unavailable service, 503 for rate limiting) to improve API reliability and provide meaningful feedback to clients.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@services/routes/symptoms_route.py` around lines 13 - 14, Wrap the external
call to check_symptoms in the symptoms_route handler with a try/except that
catches network/HTTP/auth/rate-limit errors from the Groq client and returns
structured JSON responses with appropriate status codes; for
transient/unavailable service errors return a 502 with a message, for rate-limit
errors return a 503 (or inspect the exception for 429 and return 429), and for
unexpected exceptions return a 500—include the error message in the JSON body
for debugging and ensure you still return via jsonify({"reply": ...}) or
jsonify({"error": ...}), using the Flask response tuple (body, status_code) to
set the HTTP status.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant