Skip to content

Commit

Permalink
Merge pull request #14 from workforce-data-initiative/expose_geo
Browse files Browse the repository at this point in the history
Expose geography
  • Loading branch information
Gregory Mundy committed Oct 31, 2016
2 parents cac97ea + 8ac750e commit 4426f69
Show file tree
Hide file tree
Showing 6 changed files with 187 additions and 0 deletions.
11 changes: 11 additions & 0 deletions README.md
Expand Up @@ -12,6 +12,7 @@ The following endpoints were automatically deployed via the Zappa framework to A

## Dependencies
- Python 2.7.11
- Postgres database

## Installation
To run the API locally, please perform the following steps:
Expand Down Expand Up @@ -45,6 +46,16 @@ $ source venv/bin/activate
$ pip install -r requirements.txt
```

8. Make regular (development) config. Run bin/make_config.sh and fill in connection string to database.
```
$ bin/make_config.sh
```

9. Clone development config for test config. Copy the resultant config/config.py to config/test_config.py and modify the SQL connection string to match your test database (you can leave this the same as your development database, if you wish, but we recommend keeping separate ones.
```
$ cp config/config.py config/test_config.py
```

## Deployment to Amazon Web Services
TODO - Write some deployment instructions here

Expand Down
21 changes: 21 additions & 0 deletions api/v1/endpoints.py
Expand Up @@ -25,6 +25,8 @@
from . models.jobs_unusual_titles import JobUnusualTitle
from . models.jobs_skills import JobSkill
from . models.skills_importance import SkillImportance
from . models.geographies import Geography
from . models.jobs_importance import JobImportance
from collections import OrderedDict

# Pagination Control Parameters
Expand Down Expand Up @@ -477,6 +479,25 @@ def get(self, id=None):
"""
if id is not None:
args = request.args

if args is not None:
geography = None
if 'fips' in args.keys():
fips = args['fips']
geography = Geography.query.filter_by(
geography_type = 'CBSA',
geography_name = fips
).first()
if geography is None:
return create_error('Core-Based Statistical Area FIPS code not found', 404)
importance = JobImportance.query.filter_by(
geography_id = geography.geography_id,
job_uuid = id
).first()
if importance is None:
return create_error('Job not found in given Core-Based statistical area', 404)

result = JobMaster.query.filter_by(onet_soc_code = id).first()
if result is None:
result = JobMaster.query.filter_by(uuid = id).first()
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Expand Up @@ -17,6 +17,7 @@ Flask-RESTful==0.3.5
Flask-Script==2.0.5
Flask-SQLAlchemy==2.1
Flask-Elasticsearch
factory_boy
futures==3.0.5
HTTPretty
hjson==1.5.6
Expand Down
17 changes: 17 additions & 0 deletions tests/api_test_case.py
@@ -0,0 +1,17 @@
from app import app
import unittest
from flask_migrate import upgrade


class ApiTestCase(unittest.TestCase):
def setUp(self):
app.app.config.from_object('config.test_config.Config')
self.app = app.app.test_client()
self.app.testing = True
with app.app.app_context():
upgrade()
app.db.session.begin(subtransactions=True)

def tearDown(self):
app.db.session.rollback()
app.db.session.close()
47 changes: 47 additions & 0 deletions tests/factories.py
@@ -0,0 +1,47 @@
from app import app
from factory import alchemy, LazyAttribute, Sequence
from api.v1 import Geography, Quarter, JobImportance, JobMaster
from faker import Faker

fake = Faker()


class JobMasterFactory(alchemy.SQLAlchemyModelFactory):
class Meta(object):
model = JobMaster
sqlalchemy_session = app.db.session

uuid = Sequence(lambda n: str(n))
onet_soc_code = LazyAttribute(lambda x: fake.phone_number())
title = LazyAttribute(lambda x: fake.job())
original_title = LazyAttribute(lambda x: fake.job())
description = LazyAttribute(lambda x: fake.job())
nlp_a = LazyAttribute(lambda x: fake.job())


class GeographyFactory(alchemy.SQLAlchemyModelFactory):
class Meta(object):
model = Geography
sqlalchemy_session = app.db.session

geography_id = Sequence(lambda x: x)
geography_type = 'CBSA'
geography_name = LazyAttribute(lambda x: fake.phone_number())


class QuarterFactory(alchemy.SQLAlchemyModelFactory):
class Meta(object):
model = Quarter
sqlalchemy_session = app.db.session

quarter_id = Sequence(lambda x: x)
quarter = '3'
year = '2016'


class JobImportanceFactory(alchemy.SQLAlchemyModelFactory):
class Meta(object):
model = JobImportance
sqlalchemy_session = app.db.session

importance = 0.2
90 changes: 90 additions & 0 deletions tests/job_get_test.py
@@ -0,0 +1,90 @@
from app import app
import json
import unittest
from tests.api_test_case import ApiTestCase

from tests.factories import GeographyFactory, \
JobImportanceFactory, \
JobMasterFactory, \
QuarterFactory


class JobGetTestCase(ApiTestCase):

def test_with_uuid(self):
job = JobMasterFactory()
app.db.session.add(job)
response = self.app.get('v1/jobs/{}'.format(job.uuid))
self.assertEqual(response.status_code, 200)
response_data = json.loads(response.get_data())
self.assertEqual(response_data['title'], job.title)

def test_with_soc_code(self):
job = JobMasterFactory()
app.db.session.add(job)
response = self.app.get('v1/jobs/{}'.format(job.onet_soc_code))
self.assertEqual(response.status_code, 200)
response_data = json.loads(response.get_data())
self.assertEqual(response_data['title'], job.title)

def test_missing_geo(self):
job = JobMasterFactory()
app.db.session.add(job)
response = self.app.get('v1/jobs/{}?fips=40500'.format(job.uuid))
self.assertEqual(response.status_code, 404)

def test_geo_mismatch(self):
job = JobMasterFactory()
right_geography = GeographyFactory()
wrong_geography = GeographyFactory()
quarter = QuarterFactory()
app.db.session.begin(subtransactions=True)
app.db.session.add(job)
app.db.session.add(right_geography)
app.db.session.add(wrong_geography)
app.db.session.add(quarter)
app.db.session.commit()
importance = JobImportanceFactory(
geography_id=right_geography.geography_id,
quarter_id=quarter.quarter_id,
job_uuid=job.uuid
)
app.db.session.add(importance)
response = self.app.get(
'v1/jobs/{}?fips={}'.format(
job.uuid,
wrong_geography.geography_name
)
)
self.assertEqual(response.status_code, 404)

def test_geo_match(self):
job = JobMasterFactory()
right_geography = GeographyFactory()
wrong_geography = GeographyFactory()
quarter = QuarterFactory()
app.db.session.begin(subtransactions=True)
app.db.session.add(job)
app.db.session.add(right_geography)
app.db.session.add(wrong_geography)
app.db.session.add(quarter)
app.db.session.commit()

importance = JobImportanceFactory(
geography_id=right_geography.geography_id,
quarter_id=quarter.quarter_id,
job_uuid=job.uuid
)
app.db.session.add(importance)
response = self.app.get(
'v1/jobs/{}?fips={}'.format(
job.uuid,
right_geography.geography_name
)
)
self.assertEqual(response.status_code, 200)
response_data = json.loads(response.get_data())
self.assertEqual(response_data['title'], job.title)

if __name__ == '__main__':
unittest.main()

0 comments on commit 4426f69

Please sign in to comment.