Light Mode

Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

This commit introduces a major UI/UX redesign of the application usin...#5

Open
GYFX35 wants to merge 1 commit intomainfrom
feat/ui-ux-redesign-and-production-readiness
Open

This commit introduces a major UI/UX redesign of the application usin...#5
GYFX35 wants to merge 1 commit intomainfrom
feat/ui-ux-redesign-and-production-readiness

Conversation

Copy link
Owner

GYFX35 commented Aug 7, 2025 *
edited by sourcery-ai bot
Loading

...g Bootstrap. It also makes the application production-ready by adding a requirements.txt file, a Procfile for Gunicorn, and configuring the app to use environment variables.

The main changes are:

  • Replaced the old stylesheet with Bootstrap 5.
  • Updated all major templates to use Bootstrap components for a modern and responsive UI.
  • Added a requirements.txt file with all the necessary dependencies.
  • Added a Procfile to run the application with Gunicorn.
  • Updated the configuration to use python-dotenv to load environment variables.
  • Fixed several bugs related to missing dependencies and application startup hangs.

Summary by Sourcery

Revamp the application's UI with Bootstrap 5, make it production-ready by adding dependency and deployment configurations, and enhance API routes with error handling and timeouts.

New Features:

  • Introduce Bootstrap 5 for modern, responsive UI across all main templates
  • Add requirements.txt to pin project dependencies
  • Include a Procfile to run the application with Gunicorn
  • Configure python-dotenv to load environment variables in application config
  • Implement request timeouts and exception handling for UNESCO and WHO API endpoints

Bug Fixes:

  • Fix missing dependencies and prevent startup hangs by specifying dependencies and adding request timeouts

...g Bootstrap. It also makes the application production-ready by adding a `requirements.txt` file, a `Procfile` for Gunicorn, and configuring the app to use environment variables.

The main changes are:
- Replaced the old stylesheet with Bootstrap 5.
- Updated all major templates to use Bootstrap components for a modern and responsive UI.
- Added a `requirements.txt` file with all the necessary dependencies.
- Added a `Procfile` to run the application with Gunicorn.
- Updated the configuration to use `python-dotenv` to load environment variables.
- Fixed several bugs related to missing dependencies and application startup hangs.
Copy link

sourcery-ai bot commented Aug 7, 2025 *
edited
Loading

Reviewer's Guide

This PR overhauls the application's UI/UX by integrating Bootstrap 5 and refactoring all major templates into responsive layouts, configures production deployment with Gunicorn and dotenv support, and strengthens reliability through robust external API error handling.

Flow diagram for improved external API error handling

flowchart TD
A[User requests WHO/UNESCO data] --> B[App sends API request]
B -->|Success| C[Parse and display data]
B -->|Error/Timeout| D[Show error message to user]
Loading

File-Level Changes

Change Details Files
Integrate Bootstrap 5 into base layout and remove custom CSS
  • Replace local stylesheet link with Bootstrap CDN
  • Refactor navbar to Bootstrap components with toggler and dropdown
  • Wrap content in container with spacing utilities
  • Convert flash messages to Bootstrap alerts
  • Remove static style.css
  • Include Bootstrap JS bundle
templates/base.html
static/style.css
Refactor page templates with Bootstrap cards, forms, and grids
  • Wrap forms and pages in card components using form-control and form-label
  • Convert post listings and messages to Bootstrap cards and list-groups
  • Use grid system for responsive layout on index, register, login, user, messages pages
  • Apply badges and utility classes for metadata and buttons
templates/index.html
templates/register.html
templates/login.html
templates/user.html
templates/messages.html
Add production deployment setup
  • Add requirements.txt with all dependencies
  • Create Procfile for Gunicorn entry
  • Enable python-dotenv in config and load .env
  • Update run.py to bind host 0.0.0.0 and port 8080
requirements.txt
Procfile
config.py
run.py
Enhance external API reliability with error handling
  • Wrap UNESCO and WHO data requests in try/except blocks
  • Add request timeouts and raise_for_status checks
  • Flash user-friendly error messages on request failures
  • Fallback to empty data on failures
app/routes.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link

guardrails bot commented Aug 7, 2025

We detected 3 security issues in this pull request:

Vulnerable Libraries (3)
Severity Details
N/A pkg:pypi/flask@0.0.0 (t) upgrade to: 1.0
High pkg:pypi/gunicorn@0.0.0 upgrade to: 19.5.0
Medium pkg:pypi/requests@0.0.0 upgrade to: 2.32.4

More info on how to fix Vulnerable Libraries in Python.


Go to the dashboard for detailed results.

Happy? Share your feedback with us.

sourcery-ai bot reviewed Aug 7, 2025
Copy link

sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey @GYFX35 - I've reviewed your changes and found some issues that need to be addressed.

Blocking issues:

  • Running with debug=True in production is a security risk. (link)

General comments:

  • Pin dependency versions in requirements.txt to ensure reproducible builds and avoid unexpected upgrades.
  • Remove debug=True from run.py in production mode and control debug configuration via environment variables.
  • Add SRI integrity and crossorigin attributes to your CDN Bootstrap and jQuery script tags to improve security.
Prompt for AI Agents
Consider more granular error handling for UNESCO API requests. Wrapping each API request in its own try/except block would allow the function to return available data even if some requests fail. <<<<<<< SEARCH try: for code, name in indicators.items(): url = f"http://data.uis.unesco.org/api/v1/data/indicator/{code}?fo rmat=json" response = requests.get(url, timeout=10) response.raise_for_status() data[name] = response.json()['dataSets'][0]['series'] except requests.exceptions.RequestException as e: flash(f"Could not retrieve data from UNESCO API: {e}") data = {} ======= for code, name in indicators.items(): url = f"http://data.uis.unesco.org/api/v1/data/indicator/{code}?fo rmat=json" try: response = requests.get(url, timeout=10) response.raise_for_status() data[name] = response.json()['dataSets'][0]['series'] except requests.exceptions.RequestException as e: flash(f"Could not retrieve data for '{name}' from UNESCO API: {e}", "warning") >>>>>>> REPLACE ### Comment 2 `templates/base.html:77` + {% with messages = get_flashed_messages(with_categories=true) %} + {% if messages %} + {% for category, message in messages %} +
{{ message }}
+ {% endfor %} + {% endif %}
Flashed message categories may not map directly to Bootstrap alert classes. If your flash categories differ from Bootstrap's expected values, map them accordingly to ensure correct alert styling. <<<<<<< SEARCH {% with messages = get_flashed_messages(with_categories=true) %} {% if messages %} {% for category, message in messages %}
{{ message }}
{% endfor %} {% endif %} ======= {% set bootstrap_alert_map = { 'error': 'danger', 'message': 'info', 'info': 'info', 'success': 'success', 'warning': 'warning', 'danger': 'danger' } %} {% with messages = get_flashed_messages(with_categories=true) %} {% if messages %} {% for category, message in messages %}
{{ message }}
{% endfor %} {% endif %} >>>>>>> REPLACE
### Comment 3 `run.py:4` if __name__ == '__main__': - app.run(debug=True) + app.run(host='0.0.0.0', port=8080, debug=True) Running with debug=True in production is a security risk. Use environment variables or configuration files to manage the debug setting and ensure it is disabled in production. ">Please address the comments from this code review:
## Overall Comments
- Pin dependency versions in requirements.txt to ensure reproducible builds and avoid unexpected upgrades.
- Remove debug=True from run.py in production mode and control debug configuration via environment variables.
- Add SRI integrity and crossorigin attributes to your CDN Bootstrap and jQuery script tags to improve security.

## Individual Comments

### Comment 1
<location> `app/routes.py:208` location>

- url = f"http://data.uis.unesco.org/api/v1/data/indicator/{code}?format=json"
- response = requests.get(url)
- data[name] = response.json()['dataSets'][0]['series']
+ try:
+ for code, name in indicators.items():
+ url = f"http://data.uis.unesco.org/api/v1/data/indicator/{code}?format=json"
+ response = requests.get(url, timeout=10)



Consider more granular error handling for UNESCO API requests.

Wrapping each API request in its own try/except block would allow the function to return available data even if some requests fail.



<<<<<<< SEARCH
try:
for code, name in indicators.items():
url = f"http://data.uis.unesco.org/api/v1/data/indicator/{code}?format=json"
response = requests.get(url, timeout=10)
response.raise_for_status()
data[name] = response.json()['dataSets'][0]['series']
except requests.exceptions.RequestException as e:
flash(f"Could not retrieve data from UNESCO API: {e}")
data = {}
=======
for code, name in indicators.items():
url = f"http://data.uis.unesco.org/api/v1/data/indicator/{code}?format=json"
try:
response = requests.get(url, timeout=10)
response.raise_for_status()
data[name] = response.json()['dataSets'][0]['series']
except requests.exceptions.RequestException as e:
flash(f"Could not retrieve data for '{name}' from UNESCO API: {e}", "warning")
>>>>>>> REPLACE



### Comment 2
<location> `templates/base.html:77` location>

+ {% with messages = get_flashed_messages(with_categories=true) %}
+ {% if messages %}
+ {% for category, message in messages %}
+
{{ message }}

+ {% endfor %}
+ {% endif %}



Flashed message categories may not map directly to Bootstrap alert classes.

If your flash categories differ from Bootstrap's expected values, map them accordingly to ensure correct alert styling.



<<<<<<< SEARCH
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
<div class="alert alert-{{ category }}">{{ message }}div>
{% endfor %}
{% endif %}
=======
{% set bootstrap_alert_map = {
'error': 'danger',
'message': 'info',
'info': 'info',
'success': 'success',
'warning': 'warning',
'danger': 'danger'
} %}
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
{{ message }}

{% endfor %}
{% endif %}
>>>>>>> REPLACE



### Comment 3
<location> `run.py:4` location>


if __name__ == '__main__':
- app.run(debug=True)
+ app.run(host='0.0.0.0', port=8080, debug=True)



Running with debug=True in production is a security risk.

Use environment variables or configuration files to manage the debug setting and ensure it is disabled in production.

Sourcery is free for open source - if you like our reviews please consider sharing them
Help me be more useful! Please click or on each comment and I'll use the feedback to improve your reviews.

sourcery-ai[bot] reacted with thumbs up emoji sourcery-ai[bot] reacted with thumbs down emoji
Comment on lines +208 to +216
try:
for code, name in indicators.items():
url = f"http://data.uis.unesco.org/api/v1/data/indicator/{code}?format=json"
response = requests.get(url, timeout=10)
response.raise_for_status()
data[name] = response.json()['dataSets'][0]['series']
except requests.exceptions.RequestException as e:
flash(f"Could not retrieve data from UNESCO API: {e}")
data = {}
Copy link

sourcery-ai bot Aug 7, 2025

Choose a reason for hiding this comment

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

suggestion: Consider more granular error handling for UNESCO API requests.

Wrapping each API request in its own try/except block would allow the function to return available data even if some requests fail.

Suggested change
try:
for code, name in indicators.items():
url = f"http://data.uis.unesco.org/api/v1/data/indicator/{code}?format=json"
response = requests.get(url, timeout=10)
response.raise_for_status()
data[name] = response.json()['dataSets'][0]['series']
except requests.exceptions.RequestException as e:
flash(f"Could not retrieve data from UNESCO API: {e}")
data = {}
for code, name in indicators.items():
url = f"http://data.uis.unesco.org/api/v1/data/indicator/{code}?format=json"
try:
response = requests.get(url, timeout=10)
response.raise_for_status()
data[name] = response.json()['dataSets'][0]['series']
except requests.exceptions.RequestException as e:
flash(f"Could not retrieve data for '{name}' from UNESCO API: {e}", "warning")

sourcery-ai[bot] reacted with thumbs up emoji sourcery-ai[bot] reacted with thumbs down emoji
Comment on lines +74 to +79
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
{{ message }}
{% endfor %}
{% endif %}
Copy link

sourcery-ai bot Aug 7, 2025

Choose a reason for hiding this comment

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

suggestion: Flashed message categories may not map directly to Bootstrap alert classes.

If your flash categories differ from Bootstrap's expected values, map them accordingly to ensure correct alert styling.

Suggested change
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
<div class="alert alert-{{ category }}">{{ message }}div>
{% endfor %}
{% endif %}
{% set bootstrap_alert_map = {
'error': 'danger',
'message': 'info',
'info': 'info',
'success': 'success',
'warning': 'warning',
'danger': 'danger'
} %}
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
<div class="alert alert-{{ bootstrap_alert_map.get(category, 'info') }}">{{ message }}div>
{% endfor %}
{% endif %}

sourcery-ai[bot] reacted with thumbs up emoji sourcery-ai[bot] reacted with thumbs down emoji

if __name__ == '__main__':
app.run(debug=True)
app.run(host='0.0.0.0', port=8080, debug=True)
Copy link

sourcery-ai bot Aug 7, 2025

Choose a reason for hiding this comment

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

issue (security): Running with debug=True in production is a security risk.

Use environment variables or configuration files to manage the debug setting and ensure it is disabled in production.

sourcery-ai[bot] reacted with thumbs up emoji sourcery-ai[bot] reacted with thumbs down emoji
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

sourcery-ai[bot] sourcery-ai[bot] left review comments

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

1 participant