-
Notifications
You must be signed in to change notification settings - Fork 44
C22 - Sphinx - Tatiana Trofimova #38
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
a5d2d10
8ad364a
11048e4
20dabc8
af10725
1a41d60
4d17fc6
a6094b6
7d877be
991f860
055a22f
2858943
3c6bb1f
ededb67
4bdfaec
0589dab
360a353
23f70c1
b4031cc
d96de8b
81eb790
e328024
d2fbaf4
db350a8
b4c37a8
a8c75bb
d910bdf
490d343
94df535
cb0af09
e391da3
e93fc24
edc1841
0039a99
f9521b9
3302239
a6dcf4a
b49f6a0
2b73458
4c54403
d32dfb3
1ca3859
4d92b7d
3fee895
c440a7b
069d7ec
583722c
3457fe4
ed09c67
6716d2a
a4943da
82fc58d
4eb37c0
5755c17
0db806a
321b6bd
485dac5
a92db83
2e4dc64
10c2c39
721fe94
52da2dc
2ffdc3f
a2bf5ed
1b51387
09f89e9
363fb62
5ceb059
f22a456
acca02a
c2e586d
5c178dd
53f779c
6052392
b15e2d0
011e936
c904e75
051049f
6507919
4697786
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -138,4 +138,7 @@ dmypy.json | |
.pytype/ | ||
|
||
# Cython debug symbols | ||
cython_debug/ | ||
cython_debug/ | ||
|
||
# Slack bot logo | ||
slack_bot_logo.png |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
--- | ||
dist: focal | ||
language: python | ||
python: | ||
- "3.9" | ||
services: | ||
- postgresql | ||
addons: | ||
postgresql: "13" | ||
env: | ||
global: | ||
- SQLALCHEMY_TEST_DATABASE_URI=postgresql+psycopg2://postgres@localhost:5432/task_list_api_test | ||
before_install: | ||
- sudo apt-get update | ||
- sudo apt-get install -y postgresql-13 postgresql-client-13 | ||
before_script: | ||
- echo "Starting PostgreSQL..." | ||
- sudo sed -i 's/#port = 5432/port = 5432/' | ||
/etc/postgresql/13/main/postgresql.conf | ||
- sudo systemctl restart postgresql || sudo service postgresql start | ||
- psql --version | ||
- psql -c 'create database task_list_api_test;' -U postgres || true | ||
- psql -c '\l' -U postgres | ||
- curl --version | ||
install: | ||
- pip install -r requirements.txt | ||
script: | ||
- pytest | ||
after_success: | ||
- echo "Deploying to Render..." | ||
- echo "RENDER_API_KEY: ${RENDER_API_KEY}" | ||
- curl -X POST "https://api.render.com/deploy/srv-csmrpdaj1k6c73dnhqi0?key=hVyereic-JM" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
MIT License | ||
|
||
Copyright (c) 2024 Tatiana Trofimova | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,57 +1,126 @@ | ||
# Task List API | ||
|
||
## Skills Assessed | ||
# Task List API Backend | ||
|
||
- Gathering technical requirements from written documentation | ||
- Reading, writing, and using tests | ||
- Demonstrating understanding of the client-server model, request-response cycle and conventional RESTful routes | ||
- Driving development with independent research, experimentation, and collaboration | ||
- Reading and using existing external web APIs | ||
- Using Postman as part of the development workflow | ||
- Using git as part of the development workflow | ||
A backend RESTful API built with Flask to manage tasks and goals in a full-stack project. The API is integrated with a PostgreSQL database and provides endpoints for creating, reading, updating, and deleting tasks and goals. | ||
|
||
## About the Project | ||
|
||
This backend application is part of a full-stack project created to practice and strengthen skills in backend development, API design, and database integration. It serves as the server-side component of the TaskList application. | ||
|
||
### Deployed Application | ||
|
||
- **Backend Deployment**: [Deployed Backend on Render](https://task-list-api-ai13.onrender.com) | ||
- **Frontend Deployment**: [Deployed Frontend on GitHub Pages](https://nerpassevera.github.io/task-list-front-end) | ||
|
||
## Features | ||
|
||
### Tasks | ||
- **Create Tasks**: Add new tasks. | ||
- **Delete Tasks**: Remove tasks from the list. | ||
- **Read Tasks**: Retrieve all tasks or a single task. | ||
- **Update Tasks**: Update task information. | ||
- **Mark Tasks as Completed/Incompleted**: Change the task status. | ||
- **Slack Notifications**: Notify a Slack channel when a task is marked as completed. | ||
|
||
Working with the Flask package: | ||
### Goals | ||
- **Create Goals**: Add new goals. | ||
- **Delete Goals**: Remove goals from the list. | ||
- **Read Goals**: Retrieve all goals or a single goal. | ||
- **Update Goals**: Update goal information. | ||
- **Assign Tasks to Goals**: Link multiple tasks to specific goals. | ||
|
||
- Creating models | ||
- Creating conventional RESTful CRUD routes for a model | ||
- Reading query parameters to create custom behavior | ||
- Create unconventional routes for custom behavior | ||
- Apply knowledge about making requests in Python, to call an API inside of an API | ||
- Apply knowledge about environment variables | ||
- Creating a one-to-many relationship between two models | ||
## Technologies Used | ||
|
||
## Goals | ||
- **Flask**: Lightweight web framework for Python. | ||
- **SQLAlchemy**: ORM for database management. | ||
- **Alembic**: Database migration tool. | ||
- **PostgreSQL**: Relational database for storing tasks and goals. | ||
- **Flask-CORS**: Manage Cross-Origin Resource Sharing for API. | ||
- **Python-dotenv**: Manage environment variables using a `.env` file. | ||
|
||
There's so much we want to do in the world! When we organize our goals into smaller, bite-sized tasks, we'll be able to track them more easily, and complete them! | ||
## API Endpoints | ||
|
||
If we make a web API to organize our tasks, we'll be able to create, read, update, and delete tasks as long as we have access to the Internet and our API is running! | ||
### Tasks Routes | ||
|
||
We also want to do some interesting features with our tasks. We want to be able to: | ||
| Method | Endpoint | Description | | ||
|----------|-----------------------------|------------------------------------------| | ||
| GET | `/tasks` | Retrieve all tasks. | | ||
| POST | `/tasks` | Create a new task. | | ||
| GET | `/tasks/<task_id>` | Retrieve a specific task by ID. | | ||
| PUT | `/tasks/<task_id>` | Update a specific task by ID. | | ||
| DELETE | `/tasks/<task_id>` | Delete a specific task by ID. | | ||
| PATCH | `/tasks/<task_id>/mark_complete` | Mark a task as completed. | | ||
| PATCH | `/tasks/<task_id>/mark_incomplete` | Mark a task as incomplete. | | ||
|
||
- Sort tasks | ||
- Mark them as complete | ||
- Get feedback about our task list through Slack | ||
- Organize tasks with goals | ||
### Goals Routes | ||
|
||
... and more! | ||
| Method | Endpoint | Description | | ||
|----------|-----------------------------|------------------------------------------| | ||
| GET | `/goals` | Retrieve all goals. | | ||
| POST | `/goals` | Create a new goal. | | ||
| GET | `/goals/<goal_id>` | Retrieve a specific goal by ID. | | ||
| PUT | `/goals/<goal_id>` | Update a specific goal by ID. | | ||
| DELETE | `/goals/<goal_id>` | Delete a specific goal by ID. | | ||
| POST | `/goals/<goal_id>/tasks` |Assign multiple tasks to a specific goal. | | ||
| GET | `/goals/<goal_id>/tasks` |Retrieve all tasks associated with a goal.| | ||
|
||
## How to Complete and Submit | ||
## Setup Instructions | ||
|
||
Go through the waves one-by-one and build the features of this API. | ||
### Prerequisites | ||
- Python 3.12 or higher | ||
- PostgreSQL | ||
|
||
At submission time, no matter where you are, submit the project via Learn. | ||
### Installation | ||
|
||
## Project Directions | ||
1. Clone the repository: | ||
```bash | ||
git clone https://github.com/Nerpassevera/task-list-api.git | ||
cd task-list-api | ||
``` | ||
|
||
This project is designed to fulfill the features described in detail in each wave. The tests are meant to only guide your development. | ||
2. Create and activate a virtual environment: | ||
```bash | ||
python3 -m venv venv | ||
source venv/bin/activate # On Linux/macOS | ||
venv\Scripts\activate # On Windows | ||
``` | ||
|
||
1. [Setup](ada-project-docs/setup.md) | ||
1. [Testing](ada-project-docs/testing.md) | ||
1. [Wave 1: CRUD for one model](ada-project-docs/wave_01.md) | ||
1. [Wave 2: Using query params](ada-project-docs/wave_02.md) | ||
1. [Wave 3: Creating custom endpoints](ada-project-docs/wave_03.md) | ||
1. [Wave 4: Using an external web API](ada-project-docs/wave_04.md) | ||
1. [Wave 5: Creating a second model](ada-project-docs/wave_05.md) | ||
1. [Wave 6: Establishing a one-to-many relationship between two models](ada-project-docs/wave_06.md) | ||
1. [Wave 7: Deployment](ada-project-docs/wave_07.md) | ||
1. [Optional Enhancements](ada-project-docs/optional-enhancements.md) | ||
3. Install dependencies: | ||
```bash | ||
pip install -r requirements.txt | ||
``` | ||
|
||
4. Set up environment variables: | ||
```bash | ||
cp .env.example .env | ||
``` | ||
|
||
Update `.env` with your database URL and Slack API key: | ||
``` | ||
SQLALCHEMY_DATABASE_URI=<your_database_url> | ||
SLACK_API_KEY=<your_slack_api_key> | ||
``` | ||
|
||
5. Run database migrations: | ||
```bash | ||
flask db upgrade | ||
``` | ||
|
||
6. Start the development server: | ||
```bash | ||
flask run | ||
``` | ||
|
||
## Future Plans | ||
|
||
- Create a meta route with information of endpoints available | ||
- Allow users to dynamically change the Slack channel for notifications. | ||
- Create user accounts | ||
|
||
## Author | ||
|
||
- [Tatiana Trofimova](https://github.com/Nerpassevera) | ||
|
||
## License | ||
|
||
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
# Task List API | ||
|
||
## Skills Assessed | ||
|
||
- Gathering technical requirements from written documentation | ||
- Reading, writing, and using tests | ||
- Demonstrating understanding of the client-server model, request-response cycle and conventional RESTful routes | ||
- Driving development with independent research, experimentation, and collaboration | ||
- Reading and using existing external web APIs | ||
- Using Postman as part of the development workflow | ||
- Using git as part of the development workflow | ||
|
||
Working with the Flask package: | ||
|
||
- Creating models | ||
- Creating conventional RESTful CRUD routes for a model | ||
- Reading query parameters to create custom behavior | ||
- Create unconventional routes for custom behavior | ||
- Apply knowledge about making requests in Python, to call an API inside of an API | ||
- Apply knowledge about environment variables | ||
- Creating a one-to-many relationship between two models | ||
|
||
## Goals | ||
|
||
There's so much we want to do in the world! When we organize our goals into smaller, bite-sized tasks, we'll be able to track them more easily, and complete them! | ||
|
||
If we make a web API to organize our tasks, we'll be able to create, read, update, and delete tasks as long as we have access to the Internet and our API is running! | ||
|
||
We also want to do some interesting features with our tasks. We want to be able to: | ||
|
||
- Sort tasks | ||
- Mark them as complete | ||
- Get feedback about our task list through Slack | ||
- Organize tasks with goals | ||
|
||
... and more! | ||
|
||
## How to Complete and Submit | ||
|
||
Go through the waves one-by-one and build the features of this API. | ||
|
||
At submission time, no matter where you are, submit the project via Learn. | ||
|
||
## Project Directions | ||
|
||
This project is designed to fulfill the features described in detail in each wave. The tests are meant to only guide your development. | ||
|
||
1. [Setup](ada-project-docs/setup.md) | ||
1. [Testing](ada-project-docs/testing.md) | ||
1. [Wave 1: CRUD for one model](ada-project-docs/wave_01.md) | ||
1. [Wave 2: Using query params](ada-project-docs/wave_02.md) | ||
1. [Wave 3: Creating custom endpoints](ada-project-docs/wave_03.md) | ||
1. [Wave 4: Using an external web API](ada-project-docs/wave_04.md) | ||
1. [Wave 5: Creating a second model](ada-project-docs/wave_05.md) | ||
1. [Wave 6: Establishing a one-to-many relationship between two models](ada-project-docs/wave_06.md) | ||
1. [Wave 7: Deployment](ada-project-docs/wave_07.md) | ||
1. [Optional Enhancements](ada-project-docs/optional-enhancements.md) |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,5 +1,19 @@ | ||||||
from sqlalchemy.orm import Mapped, mapped_column | ||||||
from sqlalchemy.orm import Mapped, mapped_column, relationship | ||||||
from sqlalchemy import String | ||||||
from ..db import db | ||||||
|
||||||
class Goal(db.Model): | ||||||
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True) | ||||||
title: Mapped[str] = mapped_column(String(50)) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider whether the this column for |
||||||
tasks: Mapped[list["Task"]] = relationship(back_populates="goal") | ||||||
|
||||||
def to_dict(self): | ||||||
return { | ||||||
"id": self.id, | ||||||
"title": self.title | ||||||
} | ||||||
|
||||||
@classmethod | ||||||
def from_dict(cls, data): | ||||||
return Goal(title=data["title"]) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. While we can explicitly use
Suggested change
|
||||||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -1,5 +1,38 @@ | ||||||||||||||||||||||||||
from sqlalchemy.orm import Mapped, mapped_column | ||||||||||||||||||||||||||
from sqlalchemy.orm import Mapped, mapped_column, relationship | ||||||||||||||||||||||||||
from sqlalchemy import String, DateTime, ForeignKey | ||||||||||||||||||||||||||
from datetime import datetime | ||||||||||||||||||||||||||
from typing import Optional | ||||||||||||||||||||||||||
from ..db import db | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
class Task(db.Model): | ||||||||||||||||||||||||||
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True) | ||||||||||||||||||||||||||
title: Mapped[str] = mapped_column(String(50)) | ||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As with |
||||||||||||||||||||||||||
description: Mapped[str] = mapped_column(String(255)) | ||||||||||||||||||||||||||
completed_at: Mapped[Optional[datetime]] = mapped_column(DateTime) | ||||||||||||||||||||||||||
goal_id: Mapped[Optional[int]] = mapped_column(ForeignKey("goal.id")) | ||||||||||||||||||||||||||
goal: Mapped[Optional["Goal"]] = relationship(back_populates="tasks") | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
def to_dict(self): | ||||||||||||||||||||||||||
task_dict = { | ||||||||||||||||||||||||||
"id": self.id, | ||||||||||||||||||||||||||
"title": self.title, | ||||||||||||||||||||||||||
"description": self.description, | ||||||||||||||||||||||||||
"is_complete": bool(self.completed_at) | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
if self.goal_id is not None: | ||||||||||||||||||||||||||
task_dict["goal_id"] = self.goal_id | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
return task_dict | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
@classmethod | ||||||||||||||||||||||||||
def from_dict(cls, data): | ||||||||||||||||||||||||||
data["completed_at"] = data.get("completed_at", None) | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
task = Task( | ||||||||||||||||||||||||||
title=data["title"], | ||||||||||||||||||||||||||
description=data["description"], | ||||||||||||||||||||||||||
completed_at=data["completed_at"], | ||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
return task | ||||||||||||||||||||||||||
Comment on lines
+32
to
+38
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since you don't reference the variable
Suggested change
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍