This is the fourth project of the Full Stack Web Development Nanodegree program, from Udacity.
This project's goal was to create an item catalog backed with a full CRUD application, allowing to edit, delete and create new places (e.g., restaurants) and items on their catalogs (e.g., dishes). We also had to provide:
-
an API endpoint retrieving the same information available on HTML as JSON (e.g., list of places and all information available for each place's catalog, as well as for all users in the database)
-
an Oauth2 login system to protect the CRUD application from unauthenticated and unauthorized users
In addition, Python PEP8 style guide was required.
For this project, I choose to create an initial version of an app that would gather information on health facilities, including the list of accepted health insurance provider and a list of available treatment with their prices as well, for each facility. The goal is to have an easy-to-use application to retrieve the nearest, or cheapest, facility for a given condition. This type of information, especially prices, is often hidden - thus, this could be actually useful if it was a real app.
However, for this initial version, only a simple list of health insurance providers names were included, and no locality functionality were added besides the same fake address for every facility.
In order to fill the databases for this project, I chose the list of diseases from the EA classic Theme Hospital. I hope you, evaluator, will have the same laughs that I did when building this project!
To run this application, I use VirtualBox and vagrant.
Then, I forked this provided repository, which includes a Vagrant VM set for this project. So, I cloned this repo to my computer, and ran the pg_config.sh
in order to finish the VM setup.
Then, I had to create a developer's account and register my application in the two used Oauth2 providers, Google and Facebook. Finally, I downloaded my client_secrets.json
, and included in the root folder of my application. My personal client_secrets.json
are not included in this repository for security reasons. Please, use yours to properly run this application.
Assuming that you've the same environment described above:
-
First, you need to initiate the database:
python initiate_database.py
-
Then, you've to fill it with data: python
fill_database.py
-
Next, you need to run the webserver (that will be serving on the port 5000):
python hospitals.py
-
Finally, you must access the project on your browser:
http://localhost:5000
If you're not in the same environment as described above, I do provide a requirements.txt
now. Thus, you should be able to run this app if you: pip install -r requirements.txt
.
FIRST TIMER ALERT: As I wasn't sure if I should provide all packages' dependencies or not, I'm also including a requirements_all.txt
, which is essentially the output of the pip freeze
command on my Vagrant VM. So, if the first doesn't work, try the second?
The database is named themehospitals.db
, which is created and filled when running the first and second command, respectively, from #How to Run. Every additional time this command is used, more hospitals and users are included in the database, until all 50 hospital names and users names stored in the data_source.py
are used. One user can have more than one health facility, or none. Real users (e.g., you) will never be assigned as owner of a automatically created facility. The program avoids name repetition as well.
After the database is created and filled, you'll receive a status message with the number of hospitals and users included in that interaction, and the average number of conditions included for the new hospitals. There is no way, other than manually, to add conditions to existent hospitals.
If you delete the database and run this command again, a new database will be created, randomly filling its tables.
The database is composed by three tables, as follows:
Column | Type | Modifiers/Foreign Relationship |
---|---|---|
id | integer | not null default |
name | text | not null |
gender | text | not null |
text | not null | |
type | text | not null |
picture | text |
Column | Type | Modifiers/Foreign Relationship |
---|---|---|
id | integer | not null default |
name | text | not null |
accepted_insurance | text | not null |
address | text | not null |
phone | text | not null |
user_id | integer | ForeignKey(User.id) |
Column | Type | Modifiers/Foreign Relationship |
---|---|---|
id | integer | not nul default |
name | text | not null |
cause | text | not nul |
sympton | text | not null |
cure | text | not null |
type | text | not null |
cost | text | not null |
hospital_id | integer | ForeignKey(Hospital.id) |
user_id | integer | ForeignKey(User.id) |
The header image is based on the Theme Hospital logotype, and the source image for that was found here. The profile images for the fake users in the database were found on clipartmax.com. The required editing was made using Gimp.
The list of diseases was extracted from here. The price range was completely invented as this information was not available, neither was part of the game.
A total of 50 hospital names were automatically generated using a [fantasy name generator](https://www.fantasynamegenerators.com https://www.fantasynamegenerators.com/hospital-names.php). The people names also were created with the same tool, completing the source list with 25 male and 25 female names. The health insurance names were created by me, based on the top health insurance companies of the US.
All textual data used to create and fill the database is available in lists, dictionaries or lists of tuples in the data_source.py
.
As layout/design wasn't a requirement in this project, the design used in this application was heavily based on the templates provided in the forked repository, in order to focus on the development of the actual CRUD application.
As this wasn't a requirement for this project, the design is not responsive.
The following routes/pages are currently available in this application:
Description | Type | Routes |
---|---|---|
Home page, list all Hospitals | READ | / /hospital /hospitals |
Login | /login | |
Hospital Page, list all Conditions | READ | /hospital/<int: hospital_id> /hospital/int:hospital_id/treatments/ /hospital/int:hospital_id/conditions/ |
Add a new Hospital | CREATE | /hospital/new |
Edit a Hospital | UPDATE | /hospital/<int: hospital_id>/edit |
Delete a Hospital | DELETE | /hospital/<int: hospital_id>/delete |
Add a new Condition for a Hospital | CREATE | /hospital/<int: hospital_id>/condition/new |
Edit a Condition for a Hospital | UPDATE | /hospital/<int: hospital_id>/condition/<int: condition_id>/edit |
Delete a Condition for a Hospital | DELETE | /hospital/<int: hospital_id>/condition/<int: condition_id>/delete |
Three API endpoints were added in this project:
Description | Routes |
---|---|
Get all Hospitals | /hospital/JSON /hospitals/JSON |
Get all Conditions for a given Hospital | /hospital/<int: hospital_id>/JSON; /hospital/<int: hospital_id>/conditions/JSON; /hospital/<int: hospital_id>/treatments/JSON |
Get all data for one Condition in one Hospital | /hospital/<int: hospital_id>/condition/<int: condition_id>/JSON |
I'm using both Google and Facebook Oauth2 authentication and authorization services.
This is just a learning project, not planned to be released. No copyright infringement intended.
Five bugs currently exist in this application.
- The green bar showing flash messages is bigger on a hospital page than on the homepage. Couldn't figured that out. Sorry!
- Sometimes when re-running the
python fill_database.py
command, it will cause error. The log from the error is available here. I think it's probably something that keeps the*.db
open, and thus, can't write new information on it? It's definitely a sqlite issue, not my application's issue. - Sometimes, for some reason that I simply couldn't figure out, trying to disconnect will fail. I think it has something to do with me messing around with the server, causing problems with the login_session. Or some sort of expiration time for the tokens. Not sure. Sorry! But if you don't stay logged forever neither mess around with the server, should be all right.
- According to this question on stack overflow, the access to the gender information on Google accounts might be private and therefore, inaccessible. In order to avoid potential problems with this, I simply set the gender of real users (e.g., you) to 'Who cares?'. Not a bug, just explaining I guess?