Skip to content

Commit

Permalink
10/1 Merge Changes to Prod (#211)
Browse files Browse the repository at this point in the history
* updated routes.py to show title,description and professors for each department and to show departments for the /staff

* updated .gitignore to ignore python env directories named myenv

* Adapted db to use postgres. Updated Opportunities model with search vector and create simple route to search Opportunities (with fuzzy searching)

* fixed changes requested in PR #186

* Added migration

* Added flask-migrate

* remove myenv

* black formatting

* Fixed formatting and requirements

* Added migration to Dockerfile

* Formatting

* Fixing for pr.

* Fix docker running (#201)

* fix run command

* fix run command

* hot-fix: error with running docker container

* update port number

* Attempt docker fix (#195)

* fix run command

* hot-fix: error with running docker container

* update port number

* revert run command

* Attempt docker fix (#196)

* fix run command

* hot-fix: error with running docker container

* update port number

* revert run command

* change port and fix run

* Attempt docker fix (#197)

* fix run command

* hot-fix: error with running docker container

* update port number

* revert run command

* change port and fix run

* test

* remove docker build command

* attempt more fixes

* fix healthcheck

* rename file

* correct copy command

* try to improve the docker run test to ensure things function in prod

* Update names and production details

* Only run tests on changes to python files (#204)

Only run tests on changes to python tests

* Added migration documentation.

* Bump pytest from 8.2.2 to 8.3.3

Bumps [pytest](https://github.com/pytest-dev/pytest) from 8.2.2 to 8.3.3.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](pytest-dev/pytest@8.2.2...8.3.3)

---
updated-dependencies:
- dependency-name: pytest
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>

* Update requirements

* Update requirements

* Fix docker pip install error (#214)

* install needed alpine dependencies for postgres

* run tests for more cases

---------

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: Abid Talukder <[email protected]>
Co-authored-by: Mrunal Athaley <[email protected]>
Co-authored-by: youssefr26 <[email protected]>
Co-authored-by: Ramzey <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
  • Loading branch information
6 people authored Oct 1, 2024
1 parent 429e74c commit 09c344f
Show file tree
Hide file tree
Showing 21 changed files with 722 additions and 100 deletions.
5 changes: 4 additions & 1 deletion .github/workflows/black.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
name: Black Formatter

on: [pull_request]
on:
pull_request:
paths:
- "**.py"

jobs:
lint:
Expand Down
19 changes: 17 additions & 2 deletions .github/workflows/docker-test.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,27 @@
name: Docker Build Test

on: [pull_request]
on:
pull_request:
paths:
- "**.py"
- "Dockerfile"
- "run.sh"
- "requirements.txt"

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: "Build Docker Image"
run: |
docker build .
docker build -t labconnect-backend .
- name: "Run Docker Container"
run: |
docker run -d --name labconnect-backend-container labconnect-backend
sleep 60
docker logs labconnect-backend-container
docker stop labconnect-backend-container
docker rm labconnect-backend-container
6 changes: 5 additions & 1 deletion .github/workflows/pytest.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
name: Pytest

on: [pull_request]
on:
pull_request:
paths:
- "**.py"
- "requirements.txt"

jobs:
build:
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ env/
*.DS_Store
*.db
.coverage
*.vscode
*.vscode
13 changes: 8 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,22 @@ FROM --platform=linux/amd64 python:3.12.4-alpine3.20

WORKDIR /app

RUN apk add --no-cache postgresql-dev gcc python3-dev musl-dev

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY labconnect /app/labconnect
COPY run.py .
COPY labconnect .
COPY app.py .
COPY db_init.py .
COPY config.py .
COPY run.sh .
COPY migrations .
RUN chmod +x run.sh

HEALTHCHECK --interval=10s --timeout=5s --start-period=5s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:8000 || exit 1
CMD wget --no-verbose --tries=1 --spider http://0.0.0.0:9000 || exit 1

EXPOSE 8000
EXPOSE 9000

CMD ["./run.sh"]
CMD ["/app/run.sh"]
9 changes: 2 additions & 7 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ clean:
pystarter clean

run:
gunicorn run:app -w 6 --preload --max-requests-jitter 300 --bind 0.0.0.0:8000
gunicorn app:app -w 6 --preload --max-requests-jitter 300 --bind 0.0.0.0:9000

develop:
python3 run.py
Expand All @@ -17,9 +17,4 @@ drop:
python3 db_init.py clear

create:
python3 db_init.py create

docker-build:
docker build -t labconnect-backend .
docker tag labconnect-backend enchanter77/labconnect-backend
docker push enchanter77/labconnect-backend
python3 db_init.py create
25 changes: 17 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,16 @@
```
## Deployment
* TBD, planning to use an RPI VM
Create PRs to release branch, upon merge a new docker container will be created and pushed. This will be planned for weekly pushes on Tuesdays.
## Production
* Run gunicorn
Use the docker container in the packages tab. You can set these environment variables:
- SECRET_KEY
- JWT_SECRET_KEY
- FRONTEND_URL
- DB
* Run gunicorn to test how the service runs in production
```sh
$ make run
```
Expand All @@ -125,20 +131,23 @@ Running list of contributors to the LabConnect project:
### Rensselaer Center for Open Source Development Team
- **Siddhi W** [Frontend]
- **Siddhi W** [Frontend / Backend]
- **Mrunal A** [Frontend / Backend]
- **Abid T** [Frontend / Backend]
- **Sarah** [Backend]
- **Ramzey** [Backend]
- **Will** [Frontend]
- **Nelson** [Backend]
- **Sarah W** [Backend]
- **Ramzey Y** [Backend]
- **Will B** [Frontend]
- - **Sidarth E** [Frontend]
### Past Rensselaer Center for Open Source Development Team
- **Abid T** [Frontend / Backend]
- **Nelson** [Backend]
- **Duy L** [Database Systems]
- **Yash K** [Frontend]
- **Sam B** [Scraping / Integration]
### Special Thanks
We extend our special thanks support and opportunity provided by the RCOS community.
Expand Down
2 changes: 1 addition & 1 deletion run.py → app.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
app = create_app()

if __name__ == "__main__":
app.run(port=8000)
app.run(port=9000)
3 changes: 2 additions & 1 deletion config.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ class TestingConfig(Config):
DEBUG = True

# Using SQLLITE locally
SQLALCHEMY_DATABASE_URI = f"sqlite:///{os.path.join(basedir, 'database.db')}"
# SQLALCHEMY_DATABASE_URI = f"sqlite:///{os.path.join(basedir, 'database.db')}"
SQLALCHEMY_DATABASE_URI = "postgresql+psycopg2://postgres:root@localhost/labconnect"


class ProductionConfig(Config):
Expand Down
22 changes: 14 additions & 8 deletions db_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,15 @@
"School of Engineering",
),
(
"Areonautical Engineering",
"Aeronautical Engineering",
"flying, need for speed",
"School of Engineering",
),
(
"Material Science",
"Creating the best materials",
"School of Engineering",
),
)

for row_tuple in rpi_departments_rows:
Expand All @@ -78,6 +83,13 @@
db.session.add(row)
db.session.commit()

class_years_rows = (2024, 2025, 2026, 2027, 2028, 2029, 2030, 2031)

for row_item in class_years_rows:
row = ClassYears(class_year=row_item, active=True)
db.session.add(row)
db.session.commit()

lab_manager_rows = (
("led", "Duy", "Le", "Computer Science"),
("turner", "Wes", "Turner", "Computer Science"),
Expand Down Expand Up @@ -235,20 +247,14 @@
("BIOL", "Biological Science"),
("MATH", "Mathematics"),
("COGS", "Cognitive Science"),
("PHYS", "Physics"),
)

for row_tuple in majors_rows:
row = Majors(code=row_tuple[0], name=row_tuple[1])
db.session.add(row)
db.session.commit()

class_years_rows = (2024, 2025, 2026, 2027, 2028, 2029, 2030, 2031)

for row_item in class_years_rows:
row = ClassYears(class_year=row_item, active=True)
db.session.add(row)
db.session.commit()

# https://www.geeksforgeeks.org/datetime-timezone-in-sqlalchemy/
# https://www.tutorialspoint.com/handling-timezone-in-python

Expand Down
5 changes: 4 additions & 1 deletion labconnect/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,20 @@
# Import Flask modules
from flask import Flask
from flask_cors import CORS

from flask_jwt_extended import (
JWTManager,
create_access_token,
get_jwt,
get_jwt_identity,
)
from flask_sqlalchemy import SQLAlchemy

from flask_migrate import Migrate
from labconnect.helpers import OrJSONProvider

# Create Database object
db = SQLAlchemy()
migrate = Migrate()
jwt = JWTManager()


Expand All @@ -42,6 +44,7 @@ def initialize_extensions(app) -> None:
# Since the application instance is now created, pass it to each Flask
# extension instance to bind it to the Flask application instance (app)
db.init_app(app)
migrate.init_app(app, db)
jwt.init_app(app)
app.json = OrJSONProvider(app)

Expand Down
45 changes: 41 additions & 4 deletions labconnect/main/opportunity_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,47 @@
RecommendsClassYears,
RecommendsMajors,
RecommendsCourses,
User,
)

from labconnect.helpers import LocationEnum

from . import main_blueprint


@main_blueprint.route("/searchOpportunity/<string:input>", methods=["GET"])
def searchOpportunity(input: str):
# Perform a search
stmt = (
db.select(Opportunities)
.where(
(
Opportunities.search_vector.match(input)
) # Full-text search using pre-generated tsvector
| (
db.func.similarity(Opportunities.name, input) >= 0.1
) # Fuzzy search on the 'name' field
| (
db.func.similarity(Opportunities.description, input) >= 0.1
) # Fuzzy search on the 'description' field
)
.order_by(
db.func.similarity(
Opportunities.name, input
).desc() # Order by similarity for fuzzy search results
)
)

data = db.session.execute(stmt).scalars().all()

results = []

for opportunity in data:
results.append(opportunity.to_dict())

return results


@main_blueprint.get("/opportunity")
def getOpportunity2():

Expand Down Expand Up @@ -121,7 +155,8 @@ def packageIndividualOpportunity(opportunityInfo):
data["department"] = queryInfo[0][1].department_id

for i, item in enumerate(queryInfo):
data["author"] += item[1].name
data["author"] += item[1].getName()
# data["author"] += "look at def packageIndividualOpportunity(opportunityInfo):"
if i != len(queryInfo) - 1:
data["author"] += ", "

Expand Down Expand Up @@ -151,7 +186,7 @@ def packageOpportunityCard(opportunity):
professorInfo = ""

for i, item in enumerate(data):
professorInfo += item[1].name
professorInfo += item[1].getName()
if i != len(data) - 1:
professorInfo += ", "

Expand Down Expand Up @@ -188,7 +223,8 @@ def getOpportunity(opp_id: int):
return {"data": oppData}


@main_blueprint.get("/opportunity/filter")
# @main_blueprint.get("/opportunity/filter")
@main_blueprint.route("/opportunity/filter", methods=["GET", "POST"])
def filterOpportunities():

if not request.data:
Expand Down Expand Up @@ -491,10 +527,11 @@ def getOpportunityByProfessor(rcs_id: str):
def getProfessorOpportunityCards(rcs_id: str):
if request.method == "GET":
# query database for opportunity
user = db.first_or_404(db.select(User).where(User.email == rcs_id))

query = db.session.execute(
db.select(Opportunities, Leads)
.where(Leads.lab_manager_id == rcs_id)
.where(Leads.lab_manager_id == user.lab_manager_id)
.join(Opportunities, Leads.opportunity_id == Opportunities.id)
)

Expand Down
Loading

0 comments on commit 09c344f

Please sign in to comment.