├── .github └── workflows │ └── manual.yml ├── .gitignore ├── 1_Requests_Review ├── backend │ ├── flaskr │ │ └── __init__.py │ └── models.py └── frontend │ ├── package-lock.json │ ├── package.json │ ├── public │ ├── index.html │ └── manifest.json │ └── src │ ├── App.js │ ├── App.test.js │ ├── components │ ├── Book.js │ └── FormView.js │ ├── cover.jpg │ ├── index.js │ ├── logo.svg │ ├── serviceWorker.js │ ├── star-black.png │ ├── star.png │ ├── stylesheets │ ├── App.css │ ├── Book.css │ ├── FormView.css │ └── index.css │ └── trash.png ├── 1_Requests_Starter ├── README.md ├── backend │ ├── books.psql │ ├── flaskr │ │ └── __init__.py │ ├── models.py │ ├── requirements.txt │ └── setup.sql ├── frontend │ ├── package-lock.json │ ├── package.json │ ├── public │ │ ├── index.html │ │ └── manifest.json │ └── src │ │ ├── App.js │ │ ├── App.test.js │ │ ├── components │ │ ├── Book.js │ │ └── FormView.js │ │ ├── cover.jpg │ │ ├── index.js │ │ ├── logo.svg │ │ ├── serviceWorker.js │ │ ├── star-black.png │ │ ├── star.png │ │ ├── stylesheets │ │ ├── App.css │ │ ├── Book.css │ │ ├── FormView.css │ │ └── index.css │ │ └── trash.png └── setup.sh ├── 2_Errors_Review ├── backend │ ├── flaskr │ │ └── __init__.py │ └── models.py └── frontend │ ├── package-lock.json │ ├── package.json │ ├── public │ ├── index.html │ └── manifest.json │ └── src │ ├── App.js │ ├── App.test.js │ ├── components │ ├── Book.js │ └── FormView.js │ ├── cover.jpg │ ├── index.js │ ├── logo.svg │ ├── serviceWorker.js │ ├── star-black.png │ ├── star.png │ ├── stylesheets │ ├── App.css │ ├── Book.css │ ├── FormView.css │ └── index.css │ └── trash.png ├── 2_Errors_Starter ├── README.md ├── backend │ ├── books.psql │ ├── flaskr │ │ └── __init__.py │ ├── models.py │ ├── requirements.txt │ └── setup.sql └── frontend │ ├── package-lock.json │ ├── package.json │ ├── public │ ├── index.html │ └── manifest.json │ └── src │ ├── App.js │ ├── App.test.js │ ├── components │ ├── Book.js │ └── FormView.js │ ├── cover.jpg │ ├── index.js │ ├── logo.svg │ ├── serviceWorker.js │ ├── star-black.png │ ├── star.png │ ├── stylesheets │ ├── App.css │ ├── Book.css │ ├── FormView.css │ └── index.css │ └── trash.png ├── 3_Testing_Review ├── backend │ ├── flaskr │ │ ├── __init__.py │ │ └── __init__.pyc │ ├── models.py │ └── test_flaskr.py └── frontend │ ├── package-lock.json │ ├── package.json │ ├── public │ ├── index.html │ └── manifest.json │ └── src │ ├── App.js │ ├── App.test.js │ ├── components │ ├── Book.js │ └── FormView.js │ ├── cover.jpg │ ├── index.js │ ├── logo.svg │ ├── serviceWorker.js │ ├── star-black.png │ ├── star.png │ ├── stylesheets │ ├── App.css │ ├── Book.css │ ├── FormView.css │ └── index.css │ └── trash.png ├── 3_Testing_Starter ├── README.md ├── backend │ ├── books.psql │ ├── flaskr │ │ └── __init__.py │ ├── models.py │ ├── setup.sql │ └── test_flaskr.py └── frontend │ ├── package-lock.json │ ├── package.json │ ├── public │ ├── index.html │ └── manifest.json │ └── src │ ├── App.js │ ├── App.test.js │ ├── components │ ├── Book.js │ └── FormView.js │ ├── cover.jpg │ ├── index.js │ ├── logo.svg │ ├── serviceWorker.js │ ├── star-black.png │ ├── star.png │ └── stylesheets │ ├── App.css │ ├── Book.css │ ├── FormView.css │ └── index.css ├── 4_TDD_Review ├── backend │ ├── flaskr │ │ └── __init__.py │ ├── models.py │ ├── requirements.txt │ └── test_flaskr.py └── frontend │ ├── package-lock.json │ ├── package.json │ ├── public │ ├── index.html │ └── manifest.json │ └── src │ ├── App.js │ ├── App.test.js │ ├── components │ ├── Book.js │ └── FormView.js │ ├── cover.jpg │ ├── index.js │ ├── logo.svg │ ├── serviceWorker.js │ ├── star-black.png │ ├── star.png │ ├── stylesheets │ ├── App.css │ ├── Book.css │ ├── FormView.css │ └── index.css │ └── trash.png ├── 4_TDD_Starter ├── README.md ├── backend │ ├── books.psql │ ├── flaskr │ │ └── __init__.py │ ├── models.py │ ├── requirements.txt │ ├── setup.sql │ └── test_flaskr.py └── frontend │ ├── package-lock.json │ ├── package.json │ ├── public │ ├── index.html │ └── manifest.json │ └── src │ ├── App.js │ ├── App.test.js │ ├── components │ ├── Book.js │ └── FormView.js │ ├── cover.jpg │ ├── index.js │ ├── logo.svg │ ├── serviceWorker.js │ ├── star-black.png │ ├── star.png │ ├── stylesheets │ ├── App.css │ ├── Book.css │ ├── FormView.css │ └── index.css │ └── trash.png ├── 5_API_Doc_Review ├── README.md ├── backend │ ├── flaskr │ │ └── __init__.py │ ├── models.py │ ├── requirements.txt │ └── test_flaskr.py └── frontend │ ├── package-lock.json │ ├── package.json │ ├── public │ ├── index.html │ └── manifest.json │ └── src │ ├── App.js │ ├── App.test.js │ ├── components │ ├── Book.js │ └── FormView.js │ ├── cover.jpg │ ├── index.js │ ├── logo.svg │ ├── serviceWorker.js │ ├── star-black.png │ ├── star.png │ ├── stylesheets │ ├── App.css │ ├── Book.css │ ├── FormView.css │ └── index.css │ └── trash.png ├── 5_API_Doc_Starter ├── README.md ├── backend │ ├── flaskr │ │ └── __init__.py │ ├── models.py │ ├── requirements.txt │ └── test_flaskr.py └── frontend │ ├── package-lock.json │ ├── package.json │ ├── public │ ├── index.html │ └── manifest.json │ └── src │ ├── App.js │ ├── App.test.js │ ├── components │ ├── Book.js │ └── FormView.js │ ├── cover.jpg │ ├── index.js │ ├── logo.svg │ ├── serviceWorker.js │ ├── star-black.png │ ├── star.png │ ├── stylesheets │ ├── App.css │ ├── Book.css │ ├── FormView.css │ └── index.css │ └── trash.png ├── 6_Final_Review ├── README.md ├── backend │ ├── flaskr │ │ └── __init__.py │ ├── models.py │ ├── requirements.txt │ └── test_flaskr.py └── frontend │ ├── package-lock.json │ ├── package.json │ ├── public │ ├── index.html │ └── manifest.json │ └── src │ ├── App.js │ ├── App.test.js │ ├── components │ ├── Book.js │ └── FormView.js │ ├── cover.jpg │ ├── index.js │ ├── logo.svg │ ├── serviceWorker.js │ ├── star-black.png │ ├── star.png │ ├── stylesheets │ ├── App.css │ ├── Book.css │ ├── FormView.css │ └── index.css │ └── trash.png ├── 6_Final_Starter ├── README.md ├── backend │ ├── flaskr │ │ └── __init__.py │ ├── models.py │ ├── requirements.txt │ └── test_flaskr.py └── frontend │ ├── package-lock.json │ ├── package.json │ ├── public │ ├── index.html │ └── manifest.json │ └── src │ ├── App.js │ ├── App.test.js │ ├── components │ ├── Book.js │ └── FormView.js │ ├── cover.jpg │ ├── index.js │ ├── logo.svg │ ├── serviceWorker.js │ ├── star-black.png │ ├── star.png │ ├── stylesheets │ ├── App.css │ ├── Book.css │ ├── FormView.css │ └── index.css │ └── trash.png ├── Bookshelf_database_files ├── books.psql └── setup.sql ├── CODEOWNERS ├── Examples_from_plants_database ├── FirstFlaskApp │ └── flaskr │ │ └── __init__.py ├── Flask-CORS-Example-0 │ └── flask-cors.ipynb ├── Flask-CORS-Example-1 │ ├── flaskr │ │ └── __init__.py │ └── models.py ├── plants.psql └── plantsdb_setup.sql ├── LICENSE.md └── README.md /.github/workflows/manual.yml: -------------------------------------------------------------------------------- 1 | # Workflow to ensure whenever a Github PR is submitted, 2 | # a JIRA ticket gets created automatically. 3 | name: Manual Workflow 4 | 5 | # Controls when the action will run. 6 | on: 7 | # Triggers the workflow on pull request events but only for the master branch 8 | pull_request_target: 9 | types: [assigned, opened, reopened] 10 | 11 | # Allows you to run this workflow manually from the Actions tab 12 | workflow_dispatch: 13 | 14 | jobs: 15 | test-transition-issue: 16 | name: Convert Github Issue to Jira Issue 17 | runs-on: ubuntu-latest 18 | steps: 19 | - name: Checkout 20 | uses: actions/checkout@master 21 | 22 | - name: Login 23 | uses: atlassian/gajira-login@master 24 | env: 25 | JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }} 26 | JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }} 27 | JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }} 28 | 29 | - name: Create NEW JIRA ticket 30 | id: create 31 | uses: atlassian/gajira-create@master 32 | with: 33 | project: CONUPDATE 34 | issuetype: Task 35 | summary: | 36 | Github PR cd0037 API Development and Documentation (Disaggregated Course)| Repo: ${{ github.repository }} | PR# ${{github.event.number}} 37 | description: | 38 | Repo link: https://github.com/${{ github.repository }} 39 | PR no. ${{ github.event.pull_request.number }} 40 | PR title: ${{ github.event.pull_request.title }} 41 | PR description: ${{ github.event.pull_request.description }} 42 | In addition, please resolve other issues, if any. 43 | fields: '{"components": [{"name":"cd0037 - API Development and Documentation (Disaggregated Course)"}], "customfield_16449":"https://classroom.udacity.com/", "customfield_16450":"Resolve the PR", "labels": ["github"], "priority":{"id": "4"}}' 44 | 45 | - name: Log created issue 46 | run: echo "Issue ${{ steps.create.outputs.issue }} was created" 47 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | venv 3 | .vscode 4 | __pycache__ -------------------------------------------------------------------------------- /1_Requests_Review/backend/models.py: -------------------------------------------------------------------------------- 1 | import os 2 | from sqlalchemy import Column, String, Integer, create_engine 3 | from flask_sqlalchemy import SQLAlchemy 4 | import json 5 | 6 | database_name = "bookshelf" 7 | database_path = "postgresql://{}:{}@{}/{}".format( 8 | "student", "student", "localhost:5432", database_name 9 | ) 10 | 11 | db = SQLAlchemy() 12 | 13 | """ 14 | setup_db(app) 15 | binds a flask application and a SQLAlchemy service 16 | """ 17 | 18 | 19 | def setup_db(app, database_path=database_path): 20 | app.config["SQLALCHEMY_DATABASE_URI"] = database_path 21 | app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False 22 | db.app = app 23 | db.init_app(app) 24 | db.create_all() 25 | 26 | 27 | """ 28 | Book 29 | 30 | """ 31 | 32 | 33 | class Book(db.Model): 34 | __tablename__ = "books" 35 | 36 | id = Column(Integer, primary_key=True) 37 | title = Column(String) 38 | author = Column(String) 39 | rating = Column(Integer) 40 | 41 | def __init__(self, title, author, rating): 42 | self.title = title 43 | self.author = author 44 | self.rating = rating 45 | 46 | def insert(self): 47 | db.session.add(self) 48 | db.session.commit() 49 | 50 | def update(self): 51 | db.session.commit() 52 | 53 | def delete(self): 54 | db.session.delete(self) 55 | db.session.commit() 56 | 57 | def format(self): 58 | return { 59 | "id": self.id, 60 | "title": self.title, 61 | "author": self.author, 62 | "rating": self.rating, 63 | } 64 | -------------------------------------------------------------------------------- /1_Requests_Review/frontend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bookshelf-app", 3 | "version": "0.1.0", 4 | "private": true, 5 | "proxy": "http://127.0.0.1:5000/", 6 | "dependencies": { 7 | "corsproxy": "^1.5.0", 8 | "jquery": "^3.4.1", 9 | "react": "^16.8.6", 10 | "react-dom": "^16.8.6", 11 | "react-router-dom": "^5.0.0", 12 | "react-scripts": "3.0.1" 13 | }, 14 | "scripts": { 15 | "start": "node node_modules/react-scripts/scripts/start.js", 16 | "build": "react-scripts build", 17 | "test": "react-scripts test", 18 | "eject": "react-scripts eject" 19 | }, 20 | "eslintConfig": { 21 | "extends": "react-app" 22 | }, 23 | "browserslist": { 24 | "production": [ 25 | ">0.2%", 26 | "not dead", 27 | "not op_mini all" 28 | ], 29 | "development": [ 30 | "last 1 chrome version", 31 | "last 1 firefox version", 32 | "last 1 safari version" 33 | ] 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /1_Requests_Review/frontend/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | 7 | 8 | 12 | 13 | 22 |