Skip to content

Commit

Permalink
Merge pull request #58 from GSA/add-manual-harvest-button
Browse files Browse the repository at this point in the history
Adds support for manual harvest button
  • Loading branch information
btylerburton authored May 2, 2024
2 parents d9231d8 + d2c26c3 commit 3eb5b9f
Show file tree
Hide file tree
Showing 28 changed files with 1,124 additions and 624 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ node_modules/
tmp/

# vscode debugger
.vscode/
.vscode/*
!.vscode/launch.json
.env
requirements.txt

25 changes: 25 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Python: Remote Attach",
"type": "debugpy",
"request": "attach",
"connect": {
"host": "0.0.0.0",
"port": 5678
},
"pathMappings": [
{
"localRoot": "${workspaceFolder}",
"remoteRoot": "."
}
],
"justMyCode": false,
"logToFile": true
}
]
}
6 changes: 6 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ COPY . /app

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

ARG DEV

RUN if [ $DEV ]; \
then pip install --no-cache-dir -r requirements-dev.txt; \
fi

EXPOSE 8080

ENV FLASK_APP=run.py
Expand Down
12 changes: 11 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
pypi-upload: build-dist ## Uploads new package to PyPi after clean, build
poetry publish

deps-update: ## Updates requirements.txt and requirements_dev.txt from pyproject.toml
poetry export --without-hashes --without=dev --format=requirements.txt > requirements.txt
poetry export --without-hashes --only=dev --format=requirements-dev.txt > requirements-dev.txt

# pypi-upload-test: build-dist ## Uploads new package to TEST PyPi after clean, build
# twine upload -r testpypi dist/*

Expand All @@ -10,6 +14,9 @@ build-dist: clean-dist ## Builds new package dist
build: ## build Flask app
docker compose build app

build-dev: ## build Flask app w/ dev dependencies
docker compose build app --build-arg DEV=True

clean-dist: ## Cleans dist dir
rm -rf dist/*

Expand All @@ -19,8 +26,11 @@ test: up ## Runs poetry tests, ignores ckan load
up: ## Sets up local docker environment
docker compose up -d

up-debug: ## Sets up local docker environment
docker compose -f docker-compose_debug.yml up -d

down: ## Shuts down local docker instance
docker-compose down
docker compose down

clean: ## Cleans docker images
docker compose down -v --remove-orphans
Expand Down
16 changes: 15 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ This project is using `poetry` to manage this project. Install [here](https://py

Once installed, `poetry install` installs dependencies into a local virtual environment.

We use [Ruff](https://github.com/astral-sh/ruff) to format and lint our Python files. If you use VS Code, you can install the formatter [here](https://marketplace.visualstudio.com/items?itemName=charliermarsh.ruff).

## Testing

### CKAN load testing
Expand Down Expand Up @@ -115,10 +117,22 @@ If you followed the instructions for `CKAN load testing` and `Harvester testing`
3. when there are database DDL changes, use following steps to generate migration scripts and update database:

```bash
docker compose db up
docker compose up -d db
docker compose run app flask db migrate -m "migration description"
docker compose run app flask db upgrade
```
### Debugging
*NOTE: To use the VS-Code debugger, you will first need to sacrifice the reloading support for flask*

1. Build new containers with development requirements by running `make build-dev`

2. Launch containers by running `make up-debug`

3. In VS-Code, launch debug process `Python: Remote Attach`

4. Set breakpoints

5. Visit the site at `http://localhost:8080` and invoke the route which contains the code you've set the breakpoint on.

### Deployment to cloud.gov

Expand Down
3 changes: 2 additions & 1 deletion app/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@


def create_app(testing=False):
app = Flask(__name__)

app = Flask(__name__, static_url_path="", static_folder="static")

if testing:
app.config["TESTING"] = True
Expand Down
6 changes: 2 additions & 4 deletions app/forms.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import re

from flask_wtf import FlaskForm
from wtforms import SelectField, StringField, SubmitField, TextAreaField
from wtforms import SelectField, StringField, TextAreaField
from wtforms.validators import URL, DataRequired, ValidationError


Expand All @@ -18,7 +18,7 @@ class HarvestSourceForm(FlaskForm):
)
name = StringField("Name", validators=[DataRequired()])
url = StringField("URL", validators=[DataRequired(), URL()])
emails = TextAreaField(
notification_emails = TextAreaField(
"Notification_emails", validators=[DataRequired(), validate_email_list]
)
frequency = SelectField(
Expand All @@ -35,10 +35,8 @@ class HarvestSourceForm(FlaskForm):
source_type = SelectField(
"Source Type", choices=["Datajson", "WAF"], validators=[DataRequired()]
)
submit = SubmitField("Submit")


class OrganizationForm(FlaskForm):
name = StringField("Name", validators=[DataRequired()])
logo = StringField("Logo", validators=[DataRequired()])
submit = SubmitField("Submit")
43 changes: 21 additions & 22 deletions app/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,12 +162,6 @@ def add_harvest_job(self, job_data):
self.db.rollback()
return None

# for test, will remove later
def get_all_harvest_jobs(self):
harvest_jobs = self.db.query(HarvestJob).all()
harvest_jobs_data = [HarvesterDBInterface._to_dict(job) for job in harvest_jobs]
return harvest_jobs_data

def get_harvest_job(self, job_id):
result = self.db.query(HarvestJob).filter_by(id=job_id).first()
if result is None:
Expand Down Expand Up @@ -223,14 +217,6 @@ def add_harvest_error(self, error_data):
self.db.rollback()
return None

# for test, will remove later
def get_all_harvest_errors(self):
harvest_errors = self.db.query(HarvestError).all()
harvest_errors_data = [
HarvesterDBInterface._to_dict(err) for err in harvest_errors
]
return harvest_errors_data

def get_harvest_error(self, error_id):
result = self.db.query(HarvestError).filter_by(id=error_id).first()
if result is None:
Expand Down Expand Up @@ -276,14 +262,6 @@ def add_harvest_records(self, records_data: list) -> bool:
self.db.rollback()
return None

# for test, will remove later
def get_all_harvest_records(self):
harvest_records = self.db.query(HarvestRecord).all()
harvest_records_data = [
HarvesterDBInterface._to_dict(err) for err in harvest_records
]
return harvest_records_data

def get_harvest_record(self, record_id):
result = self.db.query(HarvestRecord).filter_by(id=record_id).first()
if result is None:
Expand Down Expand Up @@ -324,3 +302,24 @@ def close(self):
self.db.remove()
elif hasattr(self.db, "close"):
self.db.close()

##### TEST INTERFACES BELOW #####
######## TO BE REMOVED ##########
def get_all_harvest_jobs(self):
harvest_jobs = self.db.query(HarvestJob).all()
harvest_jobs_data = [HarvesterDBInterface._to_dict(job) for job in harvest_jobs]
return harvest_jobs_data

def get_all_harvest_records(self):
harvest_records = self.db.query(HarvestRecord).all()
harvest_records_data = [
HarvesterDBInterface._to_dict(err) for err in harvest_records
]
return harvest_records_data

def get_all_harvest_errors(self):
harvest_errors = self.db.query(HarvestError).all()
harvest_errors_data = [
HarvesterDBInterface._to_dict(err) for err in harvest_errors
]
return harvest_errors_data
8 changes: 7 additions & 1 deletion app/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,13 @@ class HarvestJob(Base):
db.String(36), db.ForeignKey("harvest_source.id"), nullable=False
)
status = db.Column(
Enum("new", "in_progress", "complete", name="job_status"),
Enum(
"in_progress",
"complete",
"pending",
"pending_manual",
name="job_status",
),
nullable=False,
index=True,
)
Expand Down
Loading

1 comment on commit 3eb5b9f

@github-actions
Copy link

Choose a reason for hiding this comment

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

Coverage

Coverage Report
FileStmtsMissCoverMissing
harvester
   __init__.py50100% 
   ckan_utils.py4222 95%
   exceptions.py420100% 
   harvest.py4256565 85%
   logger_config.py10100% 
   utils.py6299 85%
TOTAL5777687% 

Tests Skipped Failures Errors Time
35 0 💤 0 ❌ 0 🔥 5.722s ⏱️

Please sign in to comment.