-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
talumbau
committed
Jul 21, 2015
0 parents
commit 7a9c6fc
Showing
506 changed files
with
170,386 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
https://github.com/talumbau/conda-buildpack |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
channels: | ||
- https://conda.binstar.org/ospc | ||
- defaults |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
*.pyc | ||
*.db | ||
*.env | ||
db.sqlite3 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
echo "hello man" |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
The MIT License (MIT) | ||
|
||
Copyright (c) 2014 Open-Source Policy Center | ||
|
||
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. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
web: newrelic-admin run-program gunicorn webapp.wsgi --log-file - | ||
worker: celery -A webapp.apps.taxbrain.tasks worker -P eventlet -l info |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
Taxbrain Web Application | ||
======================== | ||
|
||
# Deploying To Heroku | ||
|
||
Production | ||
---------- | ||
Heroku relies upon GIT for deployment. The following commands are for deployment. Before deploying to Heroku make certain to run the following command* locally and commit the changes: | ||
|
||
`./manage.py collectstatic --noinput` | ||
|
||
###### * Currently this command fails to create the staticfiles dir on Heroku, so this has to be run locally and the changes committed. | ||
|
||
Deploy to Heroku: | ||
|
||
`git push heroku master` | ||
|
||
If any of the models have been updated in a deployment then those changes have to migrated so the database schema is updated. The migration should be created locally, committed, and pushed to Heroku as opposed to running the makemigration command on Heroku. Locally run the following: | ||
|
||
`./manage.py makemigrations` or `python manage.py makemigrations` (both commands have the same effect.) | ||
|
||
Commit the files that are created. | ||
|
||
In order to run those migrations, run the following commands: | ||
|
||
`heroku run ./manage.py migrate` or `heroku run python manage.py migrate` (both commands have the same effect.) | ||
|
||
Your schema will now be udpated. | ||
|
||
*DEBUG*: This should always be False on the production site. Make certain the environment variable DEV_DEBUG is set to anything but the string 'True'. To check what variables are set to in Heroku's environment run the following command: | ||
|
||
`heroku config` | ||
|
||
This will list all config variables (alternatively go to the Settings section on the Heroku dashboard and click the 'Reveal Config Vars' button.) | ||
|
||
Development | ||
----------- | ||
A live development server works exactly the same way as a production server on Heroku does. All commands and configurations are the same. The only difference is that the requirements_dev.txt can be used on this server to have access to the various debugging tools. | ||
|
||
Post deployment to a dev server runt he following command in order to install the dev tools (if desired): | ||
`heroku run pip install -r requirement_dev.txt` | ||
|
||
The migration commands presented in the Production section also hold true for development. Post deployment make sure to run the migration commands. | ||
|
||
*DEBUG*: In order to turn DEBUG on, set the DEV_DEBUG environment variable to the string 'True'. DEBUG will be off id set to anything but 'True'. In order to change the DEV_DEBUG variable use the following command: | ||
`heroku config:set DEV_DEBUG='True'` | ||
|
||
The above command will turn DEBUG on. Setting to any other string will turn DEBUG off. | ||
|
||
|
||
# Installing Locally | ||
|
||
## Installing PostgreSQL | ||
Postgres is used for this project. If PostgreSQL is not installed on your machine follow the instructions in the following links. | ||
|
||
OS X: | ||
http://www.postgresql.org/download/macosx/ | ||
|
||
Ubunutu: | ||
https://help.ubuntu.com/community/PostgreSQL | ||
|
||
Windows (should support 7 & 8): | ||
http://www.postgresql.org/download/windows/ | ||
|
||
## Create database taxcalc | ||
After PostgreSQL has been successfully installed make sure to create the taxcalc database. | ||
|
||
For Ubuntu the command is: | ||
``` | ||
createdb taxcalc | ||
``` | ||
|
||
If you need to add a user and grant permissions make sure to have psql installed as well. | ||
|
||
## Create a directory | ||
Make sure to create a directory wherever you keep your projects. | ||
|
||
``` | ||
mkdir project_name | ||
``` | ||
|
||
## Clone the repo in the new directory | ||
|
||
``` | ||
git clone [email protected]:OpenSourcePolicyCenter/webapp.git | ||
``` | ||
|
||
## Create a conda environment for your local development | ||
|
||
``` | ||
conda create -n webapp pip python=2.7 | ||
source activate webapp | ||
``` | ||
|
||
Install the required packages listed in the conda-requirements.txt file: | ||
|
||
``` | ||
conda install --file conda-requirements.txt | ||
``` | ||
|
||
Some of the packages are listed in a requirements.txt, which uses pip. Install pip: | ||
|
||
``` | ||
conda install pip | ||
``` | ||
|
||
Then use pip to install the remaining packages | ||
|
||
``` | ||
pip install -r requirements.txt | ||
``` | ||
|
||
then: | ||
|
||
``` | ||
pip install -r requirements_dev.txt | ||
``` | ||
|
||
## Using foreman | ||
Since Django can be a more involved process using foreman might be a better tool for some situations. If no work will be done on the back end, then foreman might be the tool of choice (although once Django is setup all you will have to do is run the server locally to make use of it.) | ||
|
||
Some important points: | ||
- You must start the virtual environment. | ||
- The Heroku toolbar that is installed with the requirements.txt file is expecting PostgreSQL to exist on your system. | ||
|
||
After the environment is activated the following command will start foreman: | ||
``` | ||
foreman start | ||
``` | ||
Once the server has started foreman will use port 5000. | ||
|
||
## Using Django | ||
Once all the dependecies are installed a couple of commands are necessary to get the Django project up and running and onto ```./manage.py runserver```. Make sure the virtual environment is activated. | ||
|
||
### First update the settings.py file located in the webapp dir (webapp/settings.py) | ||
In the settings.py file there is a database configuration that looks like: | ||
|
||
``` | ||
DATABASES = { | ||
'default': { | ||
'ENGINE': 'django.db.backends.postgresql_psycopg2', | ||
'NAME': 'taxcalc', | ||
'USER': 'postgres', | ||
'PASSWORD': '', | ||
'HOST': '', | ||
'PORT': '5432', | ||
} | ||
} | ||
``` | ||
1) Change the USER to your user name (the one you used to setup Postgres). | ||
2) Change the PASSWORD to the password you used to setup Postgres. | ||
3) Change HOST to 127.0.0.1 | ||
|
||
# PLEASE DO NOT COMMIT YOUR LOCAL CHANGES TO THE DATABASE CONFIG IN THE SETTINGS FILE. GIT STASH THEM! | ||
## ALTERNATIVELY, STOP TRACKING LOCAL CHANGES TO THIS FILE WITH: | ||
## `git update-index --assume-unchanged webapp/settings.py` | ||
|
||
Next change the DEBUG & TEMPLATE_DEBUG settings to True. | ||
|
||
### Second migrations have to been run. Migrations manage the schema for all database objects. Go to the root of the project simply run: | ||
``` | ||
./manage.py migrate | ||
``` | ||
Django will then run the migrations and all the tables will be created in the db. NOTE: it is critical that migrations are run when updating models, otherwise the changes to the models will not be recognized and errors will be thrown by Django (these errors tend to be increasingly informative and you will usually be prompted by Django that there are unmigrated changes when you run the local server.) | ||
|
||
### Third, it's time run the server. Simply run: | ||
``` | ||
./manage.py runserver | ||
``` | ||
|
||
Now you have a live project being run locally! | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
numba | ||
taxcalc | ||
reportlab | ||
boto | ||
gevent | ||
pillow |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
from __future__ import (absolute_import, division, print_function, | ||
unicode_literals) | ||
|
||
from gevent import monkey, get_hub | ||
from gevent.hub import LoopExit | ||
monkey.patch_all() | ||
|
||
import signal | ||
import gevent | ||
import gevent.pool | ||
from rq import Worker | ||
from rq.job import Status | ||
from rq.timeouts import BaseDeathPenalty, JobTimeoutException | ||
from rq.worker import StopRequested, green, blue | ||
from rq.exceptions import DequeueTimeout | ||
from rq.logutils import setup_loghandlers | ||
from rq.version import VERSION | ||
|
||
|
||
class GeventDeathPenalty(BaseDeathPenalty): | ||
def setup_death_penalty(self): | ||
exception = JobTimeoutException('Gevent Job exceeded maximum timeout value (%d seconds).' % self._timeout) | ||
self.gevent_timeout = gevent.Timeout(self._timeout, exception) | ||
self.gevent_timeout.start() | ||
|
||
def cancel_death_penalty(self): | ||
self.gevent_timeout.cancel() | ||
|
||
|
||
class GeventWorker(Worker): | ||
death_penalty_class = GeventDeathPenalty | ||
|
||
def __init__(self, *args, **kwargs): | ||
pool_size = 4 | ||
if 'pool_size' in kwargs: | ||
pool_size = kwargs.pop('pool_size') | ||
self.gevent_pool = gevent.pool.Pool(pool_size) | ||
super(GeventWorker, self).__init__(*args, **kwargs) | ||
|
||
def register_birth(self): | ||
super(GeventWorker, self).register_birth() | ||
self.connection.hset(self.key, 'pool_size', self.gevent_pool.size) | ||
|
||
def heartbeat(self, timeout=0): | ||
super(GeventWorker, self).heartbeat(timeout) | ||
self.connection.hset(self.key, 'curr_pool_len', len(self.gevent_pool)) | ||
|
||
def _install_signal_handlers(self): | ||
def request_force_stop(): | ||
self.log.warning('Cold shut down.') | ||
self.gevent_pool.kill() | ||
raise SystemExit() | ||
|
||
def request_stop(): | ||
if not self._stopped: | ||
gevent.signal(signal.SIGINT, request_force_stop) | ||
gevent.signal(signal.SIGTERM, request_force_stop) | ||
|
||
self.log.warning('Warm shut down requested.') | ||
self.log.warning('Stopping after all greenlets are finished. ' | ||
'Press Ctrl+C again for a cold shutdown.') | ||
|
||
self._stopped = True | ||
self.gevent_pool.join() | ||
|
||
raise StopRequested() | ||
|
||
gevent.signal(signal.SIGINT, request_stop) | ||
gevent.signal(signal.SIGTERM, request_stop) | ||
|
||
def set_current_job_id(self, job_id, pipeline=None): | ||
pass | ||
|
||
def work(self, burst=False): | ||
"""Starts the work loop. | ||
Pops and performs all jobs on the current list of queues. When all | ||
queues are empty, block and wait for new jobs to arrive on any of the | ||
queues, unless `burst` mode is enabled. | ||
The return value indicates whether any jobs were processed. | ||
""" | ||
setup_loghandlers() | ||
self._install_signal_handlers() | ||
|
||
self.did_perform_work = False | ||
self.register_birth() | ||
self.log.info('RQ worker started, version %s' % VERSION) | ||
self.set_state('starting') | ||
try: | ||
while True: | ||
if self.stopped: | ||
self.log.info('Stopping on request.') | ||
break | ||
|
||
timeout = None if burst else max(1, self.default_worker_ttl - 60) | ||
try: | ||
result = self.dequeue_job_and_maintain_ttl(timeout) | ||
|
||
if result is None and burst: | ||
try: | ||
# Make sure dependented jobs are enqueued. | ||
get_hub().switch() | ||
except LoopExit: | ||
pass | ||
result = self.dequeue_job_and_maintain_ttl(timeout) | ||
|
||
if result is None: | ||
break | ||
except StopRequested: | ||
break | ||
|
||
job, queue = result | ||
self.execute_job(job, queue) | ||
|
||
finally: | ||
if not self.is_horse: | ||
self.register_death() | ||
return self.did_perform_work | ||
|
||
def execute_job(self, job, queue): | ||
def job_done(child): | ||
self.did_perform_work = True | ||
self.heartbeat() | ||
if job.get_status() == Status.FINISHED: | ||
queue.enqueue_dependents(job) | ||
|
||
child_greenlet = self.gevent_pool.spawn(self.perform_job, job) | ||
child_greenlet.link(job_done) | ||
|
||
def dequeue_job_and_maintain_ttl(self, timeout): | ||
if self._stopped: | ||
raise StopRequested() | ||
|
||
result = None | ||
while True: | ||
if self._stopped: | ||
raise StopRequested() | ||
|
||
self.heartbeat() | ||
|
||
while self.gevent_pool.full(): | ||
gevent.sleep(0.1) | ||
if self._stopped: | ||
raise StopRequested() | ||
|
||
try: | ||
result = self.queue_class.dequeue_any(self.queues, timeout, connection=self.connection) | ||
if result is not None: | ||
job, queue = result | ||
self.log.info('%s: %s (%s)' % (green(queue.name), | ||
blue(job.description), job.id)) | ||
break | ||
except DequeueTimeout: | ||
pass | ||
|
||
self.heartbeat() | ||
return result | ||
|
Oops, something went wrong.