Compare commits

..

79 Commits

Author SHA1 Message Date
kennethreitz e9108858fc v100 2017-03-14 11:59:39 -04:00
kennethreitz c85f5d015c no debug 2017-03-14 11:43:40 -04:00
kennethreitz 321543d4ae debug 2017-03-14 11:42:02 -04:00
kennethreitz 8bd209de13 further fix test 2017-03-14 11:28:50 -04:00
kennethreitz 58e9c84347 fix tests 2017-03-14 11:27:18 -04:00
kennethreitz dcfff15151 cleanups 2017-03-14 11:23:28 -04:00
kennethreitz 9426dc8668 fix test 2017-03-14 10:54:38 -04:00
kennethreitz cdbeb6419e 2.7.11 2017-03-14 10:50:55 -04:00
kennethreitz 858113cf76 tests for newlines 2017-03-14 10:49:49 -04:00
kennethreitz a547da0b52 oops 2017-03-14 10:47:26 -04:00
kennethreitz df52fd46e5 whitespace stripper for runtime.txt 2017-03-14 10:45:59 -04:00
kennethreitz 2e37a96984 more cleanups 2017-03-14 10:00:59 -04:00
kennethreitz 12c3b8cb1d remove legacy code 2017-03-14 09:59:53 -04:00
kennethreitz 0fadebf7d8 more tests 2017-03-10 12:37:11 -05:00
kennethreitz 33ccaa9e45 bash not sh 2017-03-10 12:00:44 -05:00
kennethreitz 6b5ec50ab9 new travis matrix 2017-03-10 11:58:38 -05:00
kennethreitz 63810f29d3 passing tests 2017-03-10 11:43:11 -05:00
kennethreitz 0de749a6a2 updated tests 2017-03-10 11:22:07 -05:00
kennethreitz 2df1131d3c remove bpwatch 2017-03-10 11:21:57 -05:00
kennethreitz af0795264b heroku-16 2017-03-10 11:21:47 -05:00
kennethreitz 327daa5f32 no need for SETUPTOOLS_VERSION anymore 2017-03-08 16:58:39 -05:00
kennethreitz 09b7e44841 fix tests 2017-03-08 16:57:33 -05:00
kennethreitz e26a0f04d9 improvements 2017-03-08 09:01:24 -05:00
kennethreitz c92f379f78 improve 2017-03-08 08:58:07 -05:00
kennethreitz 893bdec066 updated setuptools 2017-03-08 08:44:32 -05:00
kennethreitz 607dcfda07 no pipenv test (for now) 2017-03-08 08:31:09 -05:00
kennethreitz 26a0b9678f no version checking yet 2017-03-07 12:09:09 -05:00
Kenneth Reitz e58e5d2b74 more tests 2017-03-07 11:58:53 -05:00
Kenneth Reitz 6faa5a4efc Merge remote-tracking branch 'origin/master' 2017-03-07 11:39:35 -05:00
kennethreitz 2881d65e4e Update pipenv 2017-03-03 09:27:42 -08:00
kennethreitz 1696e7cee6 v100! 2017-03-02 22:13:35 -08:00
kennethreitz 35b89386ed Squashed commit of the following:
commit 1b6199c182a8cf453247ae2a19b7f1db71664dda
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Thu Mar 2 22:10:46 2017 -0800

    remove toml.py

commit e9215a30f111008b97ac50584a077b77585fda4a
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Thu Mar 2 21:58:59 2017 -0800

    fuck

commit d1f40a51aa01a7f2771cbac32543e9df021939a1
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Thu Mar 2 21:58:06 2017 -0800

    frost mirror

commit 0f1ec08f8fd88d9b7ebe5b17ad3cf75a7e2859dd
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Thu Mar 2 21:45:40 2017 -0800

    hmmmm

commit 9e2e857371029f3e9569a6cbfb71e5162a991339
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Thu Mar 2 21:44:30 2017 -0800

    hmmm

commit 892ba8bfcda54db993a10546970ccfe17c3fe51d
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Thu Mar 2 21:37:46 2017 -0800

    that

commit 61f80e7f5e380e8d6237adc1589a075f2974139b
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Thu Mar 2 21:36:41 2017 -0800

    this

commit 18a6f91ef5ff4410de43c562fffee99a0fb45da0
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Thu Mar 2 21:35:32 2017 -0800

    this

commit 163acc77e59cd34ec09a0d9836bbc20448e857ad
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Thu Mar 2 21:31:53 2017 -0800

    this

commit 4af63049cd1f6ced6daf1da43b15ef98ade84497
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Thu Mar 2 21:30:52 2017 -0800

    this

commit 43bde00a088a3a5b0db3d6361b24a679e5690e8e
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Thu Mar 2 14:59:04 2017 -0800

    olive garden

commit 24305ba1b2938f3d373d0c8d158c2137eb709c82
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Thu Mar 2 14:57:52 2017 -0800

    change

commit dff928b2299679ebdee08f4e82b8815b7cbbf419
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Wed Mar 1 19:55:22 2017 -0800

    hmmm

commit e3bc14ff9085c2a0e5939693bc71930c4e299f27
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Wed Mar 1 19:45:29 2017 -0800

    pipstrip

commit 8dd06e437bb8b519d434805aa923adfd20fb0086
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Wed Mar 1 19:37:43 2017 -0800

    changes

commit 3abaaa9b9fb9b3fdd3cbd9dc2ade25f282555a65
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Wed Mar 1 19:33:59 2017 -0800

    changes

commit 61aeea92418f934ac79e189cde69bcb9e74413fe
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Wed Mar 1 19:28:15 2017 -0800

    changes

commit 9219f38ac9f56c55e0030f55dbfdd5f55ae050de
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Wed Mar 1 19:27:37 2017 -0800

    changes

commit 390f40102b946a17f58697db42edc3d6d06f6581
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Wed Mar 1 19:26:31 2017 -0800

    changes

commit bdb0710e4554764f66a753c28f260af564ef6d6a
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Wed Mar 1 19:25:24 2017 -0800

    changes

commit 3af273e7ed56a5fdec6f5986f27b4ca5312861e1
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Wed Mar 1 19:24:15 2017 -0800

    changes

commit 250632c245bcba9bb331e6ad7b6d1afd5ddc34c5
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Wed Mar 1 19:23:06 2017 -0800

    changes

commit 5c9a637a75aaf20087e80114607cc15f00b39ff3
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Wed Mar 1 19:16:47 2017 -0800

    toml.py

commit f672922a7bc09e9d7a2c559bb6be1e718703c459
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Wed Mar 1 19:15:26 2017 -0800

    vendor dir

commit 67d44200454510c3a625257909f7e708778359ec
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Wed Mar 1 19:14:45 2017 -0800

    change

commit 12dc70d7d91ce57944e221591cf3bf3bef0e0a0c
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Wed Mar 1 19:12:57 2017 -0800

    changes

commit 25673345579e8f1d7394b9ba60682f97be63273b
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Wed Mar 1 19:12:28 2017 -0800

    this

commit a4a5a6d006197158a511677d3aae25183531ff3e
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Wed Mar 1 19:07:19 2017 -0800

    changes

commit 49c2c9ab901aaa4cd9c8c168f5b388b032708e51
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Wed Mar 1 19:05:03 2017 -0800

    changes

commit 2d3223d95968408889d79f722df7628b9e4533c8
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Wed Mar 1 19:04:24 2017 -0800

    changes

commit 6334b0f62afcbb3bc91bb706d30e6dd9aadfe447
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Wed Mar 1 19:02:35 2017 -0800

    detect python version

commit df606fa0aeed0754e659cce41fa28a88c471c756
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Wed Mar 1 18:56:08 2017 -0800

    hide stderr

commit 7ac261f62ee6c38e709a1560baadc181494b97db
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Wed Mar 1 18:53:37 2017 -0800

    update

commit f8530d252c2b386fb9f65a991d94380d3eccfdfd
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Wed Mar 1 18:51:46 2017 -0800

    lock

commit 7a1e10034a591890aa16c6e34ba5cb3d6b90a7b7
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Wed Mar 1 18:50:53 2017 -0800

    just generate requriements file

commit d78630ff858394cbae8397e1d060a3cc2437943f
Merge: 766b0c6 66f5a66
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Wed Mar 1 18:49:04 2017 -0800

    Merge branch 'master' into pipenv

commit 766b0c66e742790dc45df73e021302cf18601947
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Wed Mar 1 18:47:42 2017 -0800

    semicolon wrong

commit a9017bce79a4075ed1682041ca19c54092be71bb
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Wed Mar 1 18:41:54 2017 -0800

    run pipenv

commit 651c3aa90e45aa9f7509b127e4a21110907974cf
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Wed Mar 1 18:41:45 2017 -0800

    detect on pipfile

commit 6d9f553e24b82e756dd4c02063da035025144c9b
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Wed Mar 1 18:41:37 2017 -0800

    pipenv step

commit 51c6ef3060ac707bcb0361ccbbcfca50035a4360
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Wed Mar 1 18:41:26 2017 -0800

    new vendors
2017-03-02 22:11:03 -08:00
kennethreitz 3634eb1dbf Merge branch 'master' of https://git.heroku.com/python-builder-cedar-14 2017-02-23 11:18:14 -05:00
kennethreitz 66f5a66740 update geos to geos 3.4.3 2017-02-23 11:15:39 -05:00
kennethreitz 6e2a504fc1 v99 2017-02-23 11:14:47 -05:00
kennethreitz 124aff5ea6 cleanup 2017-02-23 11:14:47 -05:00
Denis Cornehl c44ab4cd03 Don't compile static versions of geo-libraries (#339)
python uses dynamic linking, and the static libraries use 200 MB of disk
space in the dynos.
2017-02-23 11:14:31 -05:00
kennethreitz 677dfeec11 cleanup 2017-02-15 13:49:59 -05:00
kennethreitz c77a1877d3 v98 2017-02-15 13:49:08 -05:00
kennethreitz 1c51f5d84e NLTK support 2017-02-15 13:44:31 -05:00
kennethreitz 6922a82536 Update README.md 2017-02-01 15:12:21 -05:00
kennethreitz 9cc5bf1a85 Update README.md 2017-02-01 15:11:25 -05:00
kennethreitz 012cb8a4df Added more tests 2017-02-01 15:09:49 -05:00
kennethreitz fab60ae6ab more tests 2017-01-24 23:16:36 -05:00
kennethreitz cd52da6155 tell travis to run the tests 2017-01-24 23:16:36 -05:00
David Zülke acd9347930 Handle and produce leading 0 in WEB_CONCURRENCY (#355)
The Node buildpack now exports a leading zero in its numbers. This lets us detect that it (or another buildpack) set the value, and overwrite it accordingly.

Fixes the issue where adding the node buildpack to a Python app would cause only one gunicorn worker to be spawned for a 1X dyno, and not two.

We also need to again produce leading zeroes in the value, so that e.g. the PHP buildpack can do the same on boot.
2017-01-23 01:29:02 -05:00
kennethreitz d7e2f0fb08 v97 2017-01-02 11:50:49 -05:00
kennethreitz a3ed9c7155 Fix egg-links
commit cb2c57dcffe856ad547ad8fbd1907815713dc4a7
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Mon Jan 2 11:44:39 2017 -0500

    no files were found

commit 38f861f6c6dbb2825c6551f220e610bea619c27f
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Mon Jan 2 11:37:35 2017 -0500

    uninstall

commit db1db5d2a0ad364d646d378ccff62b9aa0257efd
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Mon Jan 2 11:36:41 2017 -0500

    pip cleanup

commit 2e16f233849f683ad9c9d00bad51c2dd5da11c18
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Mon Jan 2 11:35:13 2017 -0500

    uninstall

commit 078e43d2926b77a40f21026969ee930aa7ad0fee
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Mon Jan 2 11:31:39 2017 -0500

    fix

commit eff318eaf37161f0c496e130688b27d596b9cd7a
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Mon Jan 2 11:30:09 2017 -0500

    wfwef

commit d8955b452190b1b6a40049c94df564144c4607dc
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Mon Jan 2 11:28:30 2017 -0500

    oops

commit 0e83a0ae238bdea06ce0d184c8139b598f71745e
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Mon Jan 2 11:24:28 2017 -0500

    find

commit b9cb901ecb9d9075020f5c63e5faee04aade1ad7
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Mon Jan 2 11:23:04 2017 -0500

    don't

commit 3fd1a448e244a7c3f877ae75cd8672ef42a3f550
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Mon Jan 2 11:22:29 2017 -0500

    output

commit 884c6a40ee14365fccd4c9a34fb7733a833303a4
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Mon Jan 2 11:17:47 2017 -0500

    delete egg links

commit 9a16a8676abbd34b9ae0de3de4d52b4d358b2e35
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Mon Jan 2 11:14:18 2017 -0500

    remove egg-links

commit d45d9e977adc8ad7c5c18a27f1dfb20eb286bb5d
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Mon Jan 2 10:35:24 2017 -0500

    no echo

commit 5cfb64387db1c69fff57ac9afa0c996a34a4362d
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Mon Jan 2 10:33:58 2017 -0500

    debug

commit ac143097e9ee0a23464d16e2c6d414437046132e
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Mon Jan 2 10:26:27 2017 -0500

    no print 0

commit 72adfe2e4abd975f5df5350f06f93d1309ff4ed1
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Mon Jan 2 10:25:27 2017 -0500

    cat other one

commit e51e83ca3ec9a6710add90424f80f9bc7c3d5bf3
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Mon Jan 2 10:23:52 2017 -0500

    echo

commit def0231dd068fe4a854074bf42409ef373ac0977
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Mon Jan 2 10:20:31 2017 -0500

    cat the files
2017-01-02 11:48:45 -05:00
matsulib 8db1f07fba Update README.md (#354) 2016-12-30 20:17:21 -05:00
kennethreitz 17081d0328 Squashed commit of the following:
commit b611ff0cd6ed05ff27a42b6c2da656441056cfba
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Fri Dec 23 23:11:51 2016 -0500

    remove debugging statements

commit d1ab87748b
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Fri Dec 23 23:05:46 2016 -0500

    ln -s

commit 6844d1252d
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Fri Dec 23 22:55:41 2016 -0500

    further debug

commit 1346c29089
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Fri Dec 23 22:54:42 2016 -0500

    debug

commit 3bc1b5e697
Author: Kenneth Reitz <me@kennethreitz.org>
Date:   Fri Dec 23 22:53:23 2016 -0500

    say when installing pip or setuptools
2016-12-23 23:24:34 -05:00
kennethreitz d1ab87748b ln -s 2016-12-23 23:05:46 -05:00
kennethreitz 6844d1252d further debug 2016-12-23 22:55:41 -05:00
kennethreitz 1346c29089 debug 2016-12-23 22:54:42 -05:00
kennethreitz 3bc1b5e697 say when installing pip or setuptools 2016-12-23 22:53:23 -05:00
kennethreitz 9a6fa0478a Python 3.6.0 2016-12-23 12:51:20 -05:00
Jason Dusek 573ded6d41 Idempotency in symlink creation (#349) 2016-12-21 23:23:35 -05:00
kennethreitz b4ec35433a v96 2016-12-21 01:58:54 -05:00
kennethreitz cf1148f0a8 keep things in place 2016-12-20 14:04:17 -05:00
kennethreitz a0649b1e50 move things around for collectstatic 2016-12-20 14:03:12 -05:00
kennethreitz 2f2fd24421 v95 2016-12-20 13:48:47 -05:00
kennethreitz f754ae16bb capture stderr 2016-12-20 13:47:25 -05:00
kennethreitz cef1be80a5 silence find output 2016-12-20 13:41:06 -05:00
kennethreitz c0571d86bf don't fail 2016-12-20 13:39:26 -05:00
kennethreitz d82eddca03 support for pypy 2016-12-20 13:35:44 -05:00
kennethreitz 119e8145c3 move .src up for collectstatic 2016-12-20 12:09:51 -05:00
kennethreitz 99dae0f671 v92 2016-12-19 22:16:11 -05:00
kennethreitz f54dfff8a9 fix permission denied 2016-12-19 22:12:57 -05:00
kennethreitz c9760ae0ee fix deep-cp 2016-12-19 22:09:51 -05:00
kennethreitz 98ff1670b3 cleanup 2016-12-19 22:05:28 -05:00
kennethreitz bdd466f838 cleanup pip install steps, caching src 2016-12-19 22:04:51 -05:00
kennethreitz 324ebc9223 attempted fix 2016-12-19 18:03:13 -05:00
kennethreitz 42ec6d8701 remove extra stuff 2016-12-19 17:59:02 -05:00
kennethreitz 19513067bb Merge branch 'dash-e'
# Conflicts:
#	bin/compile
2016-12-19 17:58:02 -05:00
kennethreitz 753c912ecc changelog 2016-12-19 17:53:01 -05:00
kennethreitz 4e8c469ec7 deep copy 2016-12-19 17:50:31 -05:00
kennethreitz 852723f867 find all *.pth files for sed replacement 2016-12-19 16:58:31 -05:00
David Zuelke 94514a8179 fix egg links containing refs to /tmp 2016-12-19 22:52:46 +01:00
kennethreitz 7d57744c0a v90 2016-12-19 16:49:24 -05:00
kennethreitz a41ddf6bd1 skip set if no path-links are found 2016-12-19 16:48:30 -05:00
32 changed files with 2066 additions and 69 deletions
+1
View File
@@ -1,2 +1,3 @@
*.pyc *.pyc
site site
.DS_Store
+9 -2
View File
@@ -1,2 +1,9 @@
sudo: false language: bash
script: exit 0 sudo: required
services:
- docker
# install: docker pull heroku/cedar:14
script: ./tests.sh
env:
- STACK=heroku-16
- STACK=cedar-14
+50 -3
View File
@@ -1,12 +1,59 @@
# Python Buildpack Changelog # Python Buildpack Changelog
## 100
Preliminary pipenv support.
## 99
Cleanup.
## 98
Official NLTK support and other improvements.
- Support for `nltk.txt` file for declaring corpora to be downloaded.
- Leading zeros for auto-set WEB_CONCURRENCY.
## 97
Improved egg-link functionality.
## 96
Bugfix.
## 95
Improved output support.
## v94
Improved support for PyPy.
## v93
Improved support for PyPy.
## v92
Improved cache functionality and fix egg-links regression.
## v91
Bugfix, rolled back to v88.
## v90
Bugfix.
## v89 ## v89
Improved cache functionality and fix egg-links regression. Improved cache functionality and fix egg-links regression.
## v88 ## v88
Fixed bug with editable pip installations. Fixed bug with editable pip installations.
## v87 ## v87
@@ -21,7 +68,7 @@ Refactor and multi-buildpack compatibility.
## v85 ## v85
Packaging fix. Packaging fix.
## v84 ## v84
+6 -2
View File
@@ -1,8 +1,12 @@
# These targets are not files # These targets are not files
.PHONY: tests .PHONY: tests
tests: test: test-cedar-14
./bin/test
test-cedar-14:
@echo "Running tests in docker (cedar-14)..."
@docker run -v $(shell pwd):/buildpack:ro --rm -it -e "STACK=cedar-14" heroku/cedar:14 bash -c 'cp -r /buildpack /buildpack_test; cd /buildpack_test/; test/run;'
@echo ""
tools: tools:
git clone https://github.com/kennethreitz/pip-pop.git git clone https://github.com/kennethreitz/pip-pop.git
+10 -8
View File
@@ -2,6 +2,8 @@
# Heroku Buildpack: Python # Heroku Buildpack: Python
[![Build Status](https://travis-ci.org/heroku/heroku-buildpack-python.svg?branch=master)](https://travis-ci.org/heroku/heroku-buildpack-python)
This is the official [Heroku buildpack](https://devcenter.heroku.com/articles/buildpacks) for Python apps, powered by [pip](https://pip.pypa.io/) and other excellent software. This is the official [Heroku buildpack](https://devcenter.heroku.com/articles/buildpacks) for Python apps, powered by [pip](https://pip.pypa.io/) and other excellent software.
Recommended web frameworks include **Django** and **Flask**. The recommended webserver is **Gunicorn**. There are no restrictions around what software can be used (as long as it's pip-installable). Web processes must bind to `$PORT`, and only the HTTP protocol is permitted for incoming connections. Recommended web frameworks include **Django** and **Flask**. The recommended webserver is **Gunicorn**. There are no restrictions around what software can be used (as long as it's pip-installable). Web processes must bind to `$PORT`, and only the HTTP protocol is permitted for incoming connections.
@@ -21,12 +23,12 @@ Deploying a Python application couldn't be easier:
$ git push heroku master $ git push heroku master
... ...
-----> Python app detected -----> Python app detected
-----> Installing python-2.7.12 -----> Installing python-2.7.13
$ pip install -r requirements.txt $ pip install -r requirements.txt
Collecting requests (from -r requirements.txt (line 1)) Collecting requests (from -r requirements.txt (line 1))
Downloading requests-2.10.0-py2.py3-none-any.whl (501kB) Downloading requests-2.12.4-py2.py3-none-any.whl (576KB)
Installing collected packages: requests Installing collected packages: requests
Successfully installed requests-2.10.0 Successfully installed requests-2.12.4
-----> Discovering process types -----> Discovering process types
Procfile declares types -> (none) Procfile declares types -> (none)
@@ -44,11 +46,11 @@ Specify a Python Runtime
Specific versions of the Python runtime can be specified with a `runtime.txt` file: Specific versions of the Python runtime can be specified with a `runtime.txt` file:
$ cat runtime.txt $ cat runtime.txt
python-3.5.2 python-3.6.0
Runtime options include: Runtime options include:
- `python-2.7.12` - `python-2.7.13`
- `python-3.5.2` - `python-3.6.0`
- `pypy-5.3.1` (unsupported, experimental) - `pypy-5.6.0` (unsupported, experimental)
- `pypy3-2.4.0` (unsupported, experimental) - `pypy3-5.5.0` (unsupported, experimental)
+57 -37
View File
@@ -27,8 +27,9 @@ BUILD_DIR=$1
CACHE_DIR=$2 CACHE_DIR=$2
ENV_DIR=$3 ENV_DIR=$3
# Export path environment variables for sub-scripts. # Static configurations for virtualenv caches.
export BIN_DIR ROOT_DIR BUILD_DIR CACHE_DIR ENV_DIR VIRTUALENV_LOC=".heroku/venv"
LEGACY_TRIGGER="lib/python2.7"
DEFAULT_PYTHON_VERSION="python-2.7.13" DEFAULT_PYTHON_VERSION="python-2.7.13"
DEFAULT_PYTHON_STACK="cedar-14" DEFAULT_PYTHON_STACK="cedar-14"
@@ -41,7 +42,7 @@ export WARNINGS_LOG=$(mktemp)
export RECOMMENDED_PYTHON_VERSION=$DEFAULT_PYTHON_VERSION export RECOMMENDED_PYTHON_VERSION=$DEFAULT_PYTHON_VERSION
# Setup bpwatch # Setup bpwatch
export PATH=$PATH:$ROOT_DIR/vendor/bpwatch export PATH=$PATH:$ROOT_DIR/vendor/:$ROOT_DIR/vendor/bpwatch
LOGPLEX_KEY="t.b90d9d29-5388-4908-9737-b4576af1d4ce" LOGPLEX_KEY="t.b90d9d29-5388-4908-9737-b4576af1d4ce"
export BPWATCH_STORE_PATH=$CACHE_DIR/bpwatch.json export BPWATCH_STORE_PATH=$CACHE_DIR/bpwatch.json
BUILDPACK_VERSION=v28 BUILDPACK_VERSION=v28
@@ -106,12 +107,6 @@ bpwatch start pre_compile
source $BIN_DIR/steps/hooks/pre_compile source $BIN_DIR/steps/hooks/pre_compile
bpwatch stop pre_compile bpwatch stop pre_compile
# If no requirements.txt file given, assume `setup.py develop` is intended.
if [ ! -f requirements.txt ]; then
echo "-e ." > requirements.txt
fi
# Sticky runtimes. # Sticky runtimes.
if [ -f $CACHE_DIR/.heroku/python-version ]; then if [ -f $CACHE_DIR/.heroku/python-version ]; then
DEFAULT_PYTHON_VERSION=$(cat $CACHE_DIR/.heroku/python-version) DEFAULT_PYTHON_VERSION=$(cat $CACHE_DIR/.heroku/python-version)
@@ -124,6 +119,9 @@ else
CACHED_PYTHON_STACK=$STACK CACHED_PYTHON_STACK=$STACK
fi fi
# Pipenv Python version support.
source $BIN_DIR/steps/pipenv-python-version
# If no runtime given, assume default version. # If no runtime given, assume default version.
if [ ! -f runtime.txt ]; then if [ ! -f runtime.txt ]; then
echo $DEFAULT_PYTHON_VERSION > runtime.txt echo $DEFAULT_PYTHON_VERSION > runtime.txt
@@ -132,35 +130,37 @@ fi
# Prepare the cache. # Prepare the cache.
mkdir -p $CACHE_DIR mkdir -p $CACHE_DIR
# Purge "old-style" virtualenvs.
bpwatch start clear_old_venvs
[ -d $CACHE_DIR/$LEGACY_TRIGGER ] && rm -fr $CACHE_DIR/.heroku/bin $CACHE_DIR/.heroku/lib $CACHE_DIR/.heroku/include
[ -d $CACHE_DIR/$VIRTUALENV_LOC ] && rm -fr $CACHE_DIR/.heroku/venv $CACHE_DIR/.heroku/src
bpwatch stop clear_old_venvs
# Restore old artifacts from the cache. # Restore old artifacts from the cache.
bpwatch start restore_cache bpwatch start restore_cache
mkdir -p .heroku mkdir -p .heroku
cp -R $CACHE_DIR/.heroku/python .heroku/ &> /dev/null || true
cp -R $CACHE_DIR/.heroku/python-stack .heroku/ &> /dev/null || true
cp -R $CACHE_DIR/.heroku/python-version .heroku/ &> /dev/null || true
cp -R $CACHE_DIR/.heroku/vendor .heroku/ &> /dev/null || true
cp -R $CACHE_DIR/.heroku/venv .heroku/ &> /dev/null || true
if [[ -d $CACHE_DIR/.heroku/src ]]; then
cp -R $CACHE_DIR/.heroku/src .heroku/ &> /dev/null || true
fi
cp -R $CACHE_DIR/.heroku/python .heroku/ &> /dev/null || true
cp -R $CACHE_DIR/.heroku/python-stack .heroku/ &> /dev/null || true
cp -R $CACHE_DIR/.heroku/python-version .heroku/ &> /dev/null || true
cp -R $CACHE_DIR/.heroku/vendor .heroku/ &> /dev/null || true
cp -R $CACHE_DIR/.heroku/venv .heroku/ &> /dev/null || true
if [[ -d $CACHE_DIR/.heroku/src ]]; then
cp -R $CACHE_DIR/.heroku/src .heroku/ &> /dev/null || true
fi
bpwatch stop restore_cache bpwatch stop restore_cache
mkdir -p $(dirname $PROFILE_PATH) mkdir -p $(dirname $PROFILE_PATH)
# Make the directory for -e pip installations.
mkdir -p /app/.heroku/src mkdir -p /app/.heroku/src
if [[ $BUILD_DIR != '/app' ]]; then if [[ $BUILD_DIR != '/app' ]]; then
# python expects to reside in /app, so set up symlinks # python expects to reside in /app, so set up symlinks
# we will not remove these later so subsequent buildpacks can still invoke it # we will not remove these later so subsequent buildpacks can still invoke it
ln -s $BUILD_DIR/.heroku/python /app/.heroku/python ln -nsf $BUILD_DIR/.heroku/python /app/.heroku/python
ln -s $BUILD_DIR/.heroku/vendor /app/.heroku/vendor ln -nsf $BUILD_DIR/.heroku/vendor /app/.heroku/vendor
ln -s $BUILD_DIR/.heroku/venv /app/.heroku/venv ln -nsf $BUILD_DIR/.heroku/venv /app/.heroku/venv
# NOTE: /app/.heroku/src also exists, but is copied manually later. # Note: .heroku/src is copied in later.
fi fi
# Install Python. # Install Python.
@@ -169,6 +169,14 @@ source $BIN_DIR/steps/python
# Sanity check for setuptools/distribute. # Sanity check for setuptools/distribute.
source $BIN_DIR/steps/setuptools source $BIN_DIR/steps/setuptools
# Pipenv support.
source $BIN_DIR/steps/pipenv
# If no requirements.txt file given, assume `setup.py develop` is intended.
if [ ! -f requirements.txt ]; then
echo "-e ." > requirements.txt
fi
# Uninstall removed dependencies with Pip. # Uninstall removed dependencies with Pip.
source $BIN_DIR/steps/pip-uninstall source $BIN_DIR/steps/pip-uninstall
@@ -187,13 +195,19 @@ sub-env $BIN_DIR/steps/geo-libs
# GDAL support. # GDAL support.
source $BIN_DIR/steps/gdal source $BIN_DIR/steps/gdal
# Install dependencies with Pip. # Install dependencies with Pip (where the magic happens).
source $BIN_DIR/steps/pip-install source $BIN_DIR/steps/pip-install
# Support for NLTK corpora.
sub-env $BIN_DIR/steps/nltk
# Support for pip install -e.
rm -fr $BUILD_DIR/.heroku/src
deep-cp /app/.heroku/src $BUILD_DIR/.heroku/src
# Django collectstatic support. # Django collectstatic support.
sub-env $BIN_DIR/steps/collectstatic sub-env $BIN_DIR/steps/collectstatic
# Create .profile script for application runtime environment variables. # Create .profile script for application runtime environment variables.
set-env PATH '$HOME/.heroku/python/bin:$PATH' set-env PATH '$HOME/.heroku/python/bin:$PATH'
set-env PYTHONUNBUFFERED true set-env PYTHONUNBUFFERED true
@@ -207,17 +221,21 @@ set-default-env PYTHONPATH /app/
# Install sane-default script for $WEB_CONCURRENCY and $FORWARDED_ALLOW_IPS. # Install sane-default script for $WEB_CONCURRENCY and $FORWARDED_ALLOW_IPS.
cp $ROOT_DIR/vendor/python.gunicorn.sh $GUNICORN_PROFILE_PATH cp $ROOT_DIR/vendor/python.gunicorn.sh $GUNICORN_PROFILE_PATH
# Symlink the directory for -e pip installations
if [[ $BUILD_DIR != '/app' ]]; then
mv /app/.heroku/src $BUILD_DIR/.heroku
ln -s /app/.heroku/src $BUILD_DIR/.heroku/src
fi
# Experimental post_compile hook. # Experimental post_compile hook.
bpwatch start post_compile bpwatch start post_compile
source $BIN_DIR/steps/hooks/post_compile source $BIN_DIR/steps/hooks/post_compile
bpwatch stop post_compile bpwatch stop post_compile
set +e
# rewrite build dir in egg links to /app so things are found at runtime
find .heroku/python/lib/python*/site-packages/ -name "*.pth" -print0 2> /dev/null | xargs -r -0 -n 1 sed -i -e "s#$(pwd)#/app#" &> /dev/null
set -e
set +e
# Support for PyPy
find .heroku/python/lib-python/*/site-packages/ -name "*.pth" -print0 2> /dev/null | xargs -r -0 -n 1 sed -i -e "s#$(pwd)#/app#" &> /dev/null
set -e
# Store new artifacts in cache. # Store new artifacts in cache.
bpwatch start dump_cache bpwatch start dump_cache
@@ -234,7 +252,9 @@ bpwatch start dump_cache
cp -R .heroku/python-stack $CACHE_DIR/.heroku/ &> /dev/null || true cp -R .heroku/python-stack $CACHE_DIR/.heroku/ &> /dev/null || true
cp -R .heroku/vendor $CACHE_DIR/.heroku/ &> /dev/null || true cp -R .heroku/vendor $CACHE_DIR/.heroku/ &> /dev/null || true
cp -R .heroku/venv $CACHE_DIR/.heroku/ &> /dev/null || true cp -R .heroku/venv $CACHE_DIR/.heroku/ &> /dev/null || true
cp -R .heroku/src $CACHE_DIR/.heroku/ &> /dev/null || true if [[ -d .heroku/src ]]; then
cp -R .heroku/src $CACHE_DIR/.heroku/ &> /dev/null || true
fi
bpwatch stop dump_cache bpwatch stop dump_cache
+1 -1
View File
@@ -15,7 +15,7 @@
BUILD_DIR=$1 BUILD_DIR=$1
# Exit early if app is clearly not Python. # Exit early if app is clearly not Python.
if [ ! -f $BUILD_DIR/requirements.txt ] && [ ! -f $BUILD_DIR/setup.py ]; then if [ ! -f $BUILD_DIR/requirements.txt ] && [ ! -f $BUILD_DIR/setup.py ] && [ ! -f $BUILD_DIR/Pipfile ]; then
exit 1 exit 1
fi fi
Executable
+33
View File
@@ -0,0 +1,33 @@
#!/usr/bin/env bash
# This script serves as the NLTK build step of the
# [**Python Buildpack**](https://github.com/heroku/heroku-buildpack-python)
# compiler.
#
# A [buildpack](https://devcenter.heroku.com/articles/buildpacks) is an
# adapter between a Python application and Heroku's runtime.
#
# This script is invoked by [`bin/compile`](/).
# Syntax sugar.
source $BIN_DIR/utils
bpwatch start nltk_download
# Check that nltk was installed by pip, otherwise obviously not needed
python -m nltk.downloader -h >/dev/null 2>&1
if [ $? -eq 0 ]; then
puts-step "Downloading NLTK corpora..."
nltk_packages_definition="$BUILD_DIR/nltk.txt"
if [ -f "$nltk_packages_definition" ]; then
nltk_packages=$(tr "\n" " " < "$nltk_packages_definition")
puts-step "Downloading NLTK packages: $nltk_packages"
python -m nltk.downloader -d $BUILD_DIR/.heroku/python/nltk_data $nltk_packages | indent
set-env NLTK_DATA "/app/.heroku/python/nltk_data"
else
puts-warn "nltk.txt not found, not downloading any corpora"
fi
fi
bpwatch stop nltk_download
+12 -5
View File
@@ -1,6 +1,18 @@
# Install dependencies with Pip. # Install dependencies with Pip.
puts-cmd "pip install -r requirements.txt" puts-cmd "pip install -r requirements.txt"
set +e
# delete any existing egg links, to uninstall exisisting installations.
find .heroku/python/lib/python*/site-packages/ -name "*.egg-link" -delete 2> /dev/null
find .heroku/python/lib/python*/site-packages/ -name "*.pth" -print0 2> /dev/null | xargs -r -0 -n 1 sed -i -e "s#/app/#/$(pwd)/#" &> /dev/null
set -e
set +e
# Support for the above, for PyPy.
find .heroku/python/lib-python/*/site-packages/ -name "*.egg-link" -print0 2> /dev/null | xargs -r -0 -n 1 sed -i -e "s#/app/#$(pwd)/#" &> /dev/null
find .heroku/python/lib-python/*/site-packages/ -name "*.pth" -print0 2> /dev/null | xargs -r -0 -n 1 sed -i -e "s#/app/#/$(pwd)/#" &> /dev/null
set -e
[ ! "$FRESH_PYTHON" ] && bpwatch start pip_install [ ! "$FRESH_PYTHON" ] && bpwatch start pip_install
[ "$FRESH_PYTHON" ] && bpwatch start pip_install_first [ "$FRESH_PYTHON" ] && bpwatch start pip_install_first
@@ -20,11 +32,6 @@ fi
cp requirements.txt .heroku/python/requirements-declared.txt cp requirements.txt .heroku/python/requirements-declared.txt
/app/.heroku/python/bin/pip freeze --disable-pip-version-check > .heroku/python/requirements-installed.txt /app/.heroku/python/bin/pip freeze --disable-pip-version-check > .heroku/python/requirements-installed.txt
# Replace egg-links with new paths for /app.
# find .heroku/python/lib/python*/site-packages/ -name "*.egg-link" -print0 | xargs -0 cat
find .heroku/python/lib/python*/site-packages/ -name "*.egg-link" -print0 | xargs -0 -n 1 sed -i -e "s#$(pwd)/#./app/#"
find .heroku/python/lib/python*/site-packages/ -name "easy-install.pth" -print0 | xargs -0 -n 1 sed -i -e "s#$(pwd)/#/app/#"
[ ! "$FRESH_PYTHON" ] && bpwatch stop pip_install [ ! "$FRESH_PYTHON" ] && bpwatch stop pip_install
[ "$FRESH_PYTHON" ] && bpwatch stop pip_install_first [ "$FRESH_PYTHON" ] && bpwatch stop pip_install_first
+13
View File
@@ -0,0 +1,13 @@
# Generate requriements.txt with pipenv.
if [[ -f Pipfile ]]; then
if [[ ! -f requirements.txt ]]; then
puts-step "Generating 'requirements.txt' with pipenv"
pip install git+https://github.com/kennethreitz/pipenv.git#egg=pipenv &> /dev/null
pipenv lock --requirements > requirements.txt 2> /dev/null
pipstrip requirements.txt
fi
fi
+22
View File
@@ -0,0 +1,22 @@
# Detect Python-version with Pipenv.
if [[ -f $BUILD_DIR/Pipfile.lock ]]; then
if [[ ! -f $BUILD_DIR/runtime.txt ]]; then
if [[ ! -f Pipfile.lock ]]; then
pipenv lock 2> /dev/null
fi
set +e
PYTHON=$(cat $BUILD_DIR/Pipfile.lock | jq '._meta.requires.python_version' -r)
set -e
if [ "$PYTHON" = 2.7 ]; then
echo "python-2.7.13" > $BUILD_DIR/runtime.txt
fi
if [ "$PYTHON" = 3.6 ]; then
echo "python-3.6.0" > $BUILD_DIR/runtime.txt
fi
fi
fi
+1 -1
View File
@@ -13,7 +13,7 @@ indent() {
# Clean up pip output # Clean up pip output
cleanup() { cleanup() {
sed -e 's/\.\.\.\+/.../g' | sed -e '/already satisfied/Id' | sed -e '/Overwriting/Id' | sed -e '/python executable/Id' | sed -e '/no previously-included files/Id' sed -e 's/\.\.\.\+/.../g' | sed -e '/already satisfied/Id' | sed -e '/No files were found to uninstall/Id' | sed -e '/Overwriting/Id' | sed -e '/python executable/Id' | sed -e '/no previously-included files/Id'
} }
# Buildpack Indented line. # Buildpack Indented line.
+1 -1
View File
@@ -15,7 +15,7 @@ SOURCE_TARBALL='http://download.osgeo.org/gdal/1.11.1/gdal-1.11.1.tar.gz'
curl -L $SOURCE_TARBALL | tar zx curl -L $SOURCE_TARBALL | tar zx
cd gdal-1.11.1 cd gdal-1.11.1
./configure --prefix=$OUT_PREFIX && ./configure --prefix=$OUT_PREFIX --enable-static=no &&
make make
make install make install
+3 -3
View File
@@ -10,12 +10,12 @@ hash -r
echo "Building geos..." echo "Building geos..."
SOURCE_TARBALL='http://download.osgeo.org/geos/geos-3.4.2.tar.bz2' SOURCE_TARBALL='http://download.osgeo.org/geos/geos-3.4.3.tar.bz2'
curl -L $SOURCE_TARBALL | tar xj curl -L $SOURCE_TARBALL | tar xj
cd geos-3.4.2 cd geos-3.4.3
./configure --prefix=$OUT_PREFIX && ./configure --prefix=$OUT_PREFIX --enable-static=no &&
make make
make install make install
+1 -1
View File
@@ -15,7 +15,7 @@ SOURCE_TARBALL='http://download.osgeo.org/proj/proj-4.8.0.tar.gz'
curl -L $SOURCE_TARBALL | tar zx curl -L $SOURCE_TARBALL | tar zx
cd proj-4.8.0 cd proj-4.8.0
./configure --prefix=$OUT_PREFIX && ./configure --prefix=$OUT_PREFIX --enable-static=no &&
make make
make install make install
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/env bash
# Build Path: /app/.heroku/python/
# Build Deps: libraries/sqlite
OUT_PREFIX=$1
echo "Building Python..."
SOURCE_TARBALL='https://python.org/ftp/python/3.6.0/Python-3.6.0.tgz'
curl -L $SOURCE_TARBALL | tar xz
mv Python-3.6.0 src
cd src
./configure --prefix=$OUT_PREFIX --with-ensurepip=no
make
make install
ln $OUT_PREFIX/bin/python3 $OUT_PREFIX/bin/python
+1
View File
@@ -0,0 +1 @@
psycopg2
+1
View File
@@ -0,0 +1 @@
requests
+1
View File
@@ -0,0 +1 @@
python-2.7.13
+1
View File
@@ -0,0 +1 @@
requests
+1
View File
@@ -0,0 +1 @@
python-3.6.0
+1
View File
@@ -0,0 +1 @@
requests
+114
View File
@@ -0,0 +1,114 @@
Maya: Datetime for Humans™
==========================
.. image:: https://img.shields.io/pypi/v/maya.svg
:target: https://pypi.python.org/pypi/maya
.. image:: https://travis-ci.org/kennethreitz/maya.svg?branch=master
:target: https://travis-ci.org/kennethreitz/maya
.. image:: https://img.shields.io/badge/SayThanks.io-☼-1EAEDB.svg
:target: https://saythanks.io/to/kennethreitz
Datetimes are very frustrating to work with in Python, especially when dealing
with different locales on different systems. This library exists to make the
simple things **much** easier, while admitting that time is an illusion
(timezones doubly so).
Datetimes should be interacted with via an API written for humans.
Maya is mostly built around the headaches and use-cases around parsing datetime data from websites.
☤ Basic Usage of Maya
---------------------
Behold, datetimes for humans!
.. code-block:: pycon
>>> now = maya.now()
<MayaDT epoch=1481850660.9>
>>> tomorrow = maya.when('tomorrow')
<MayaDT epoch=1481919067.23>
>>> tomorrow.slang_date()
'tomorrow'
>>> tomorrow.slang_time()
'23 hours from now'
>>> tomorrow.iso8601()
'2016-12-16T15:11:30.263350Z'
>>> tomorrow.rfc2822()
'Fri, 16 Dec 2016 20:11:30 -0000'
>>> tomorrow.datetime()
datetime.datetime(2016, 12, 16, 15, 11, 30, 263350, tzinfo=<UTC>)
# Automatically parse datetime strings and generate naive datetimes.
>>> scraped = '2016-12-16 18:23:45.423992+00:00'
>>> maya.parse(scraped).datetime(to_timezone='US/Eastern', naive=True)
datetime.datetime(2016, 12, 16, 13, 23, 45, 423992)
>>> rand_day = maya.when('2011-02-07', timezone='US/Eastern')
<MayaDT epoch=1297036800.0>
# Note how this is the 6th, not the 7th.
>>> rand_day.day
6
# Always.
>>> rand_day.timezone
UTC
☤ Why is this useful?
---------------------
- All timezone algebra will behave identically on all machines, regardless of system locale.
- Complete symmetric import and export of both ISO 8601 and RFC 2822 datetime stamps.
- Fantastic parsing of both dates written for/by humans and machines (``maya.when()`` vs ``maya.parse()``).
- Support for human slang, both import and export (e.g. `an hour ago`).
- Datetimes can very easily be generated, with or without tzinfo attached.
- This library is based around epoch time, but dates before Jan 1 1970 are indeed supported, via negative integers.
- Maya never panics, and always carries a towel.
☤ What about Delorean, Arrow, & Pendulum?
-----------------------------------------
Arrow, for example, is a fantastic library, but isn't what I wanted in a datetime library. In many ways, it's better than Maya for certain things. In some ways, in my opinion, it's not.
I simply desire a sane API for datetimes that made sense to me for all the things I'd ever want to do—especially when dealing with timezone algebra. Arrow doesn't do all of the things I need (but it does a lot more!). Maya does do exactly what I need.
I think these projects complement each-other, personally. Maya is great for parsing websites. For example- Arrow supports floors and ceilings and spans of dates, which Maya does not at all.
☤ Installing Maya
-----------------
Installation is easy, with pip::
$ pip install maya
✨🍰✨
☤ Like it?
----------
`Say Thanks <https://saythanks.io/to/kennethreitz>`_!
How to Contribute
-----------------
#. Check for open issues or open a fresh issue to start a discussion around a feature idea or a bug.
#. Fork `the repository`_ on GitHub to start making your changes to the **master** branch (or branch off of it).
#. Write a test which shows that the bug was fixed or that the feature works as expected.
#. Send a pull request and bug the maintainer until it gets merged and published. :) Make sure to add yourself to AUTHORS_.
.. _`the repository`: http://github.com/kennethreitz/maya
.. _AUTHORS: https://github.com/kennethreitz/maya/blob/master/AUTHORS.rst
+273
View File
@@ -0,0 +1,273 @@
# ___ __ ___ _ _ ___
# || \/ | ||=|| \\// ||=||
# || | || || // || ||
# Ignore warnings for yaml usage.
import warnings
import ruamel.yaml
warnings.simplefilter('ignore', ruamel.yaml.error.UnsafeLoaderWarning)
import email.utils
import time
from datetime import datetime as Datetime
import pytz
import humanize
import dateparser
import iso8601
import dateutil.parser
from tzlocal import get_localzone
_EPOCH_START = (1970, 1, 1)
def validate_class_type_arguments(operator):
"""
Decorator to validate all the arguments to function
are of the type of calling class
"""
def inner(function):
def wrapper(self, *args, **kwargs):
for arg in args + tuple(kwargs.values()):
if not isinstance(arg, self.__class__):
raise TypeError('unorderable types: {}() {} {}()'.format(
type(self).__name__, operator, type(arg).__name__))
return function(self, *args, **kwargs)
return wrapper
return inner
class MayaDT(object):
"""The Maya Datetime object."""
def __init__(self, epoch):
super(MayaDT, self).__init__()
self._epoch = epoch
def __repr__(self):
return '<MayaDT epoch={}>'.format(self._epoch)
def __str__(self):
return self.rfc2822()
def __format__(self, *args, **kwargs):
"""Return's the datetime's format"""
return format(self.datetime(), *args, **kwargs)
@validate_class_type_arguments('==')
def __eq__(self, maya_dt):
return self._epoch == maya_dt._epoch
@validate_class_type_arguments('!=')
def __ne__(self, maya_dt):
return self._epoch != maya_dt._epoch
@validate_class_type_arguments('<')
def __lt__(self, maya_dt):
return self._epoch < maya_dt._epoch
@validate_class_type_arguments('<=')
def __le__(self, maya_dt):
return self._epoch <= maya_dt._epoch
@validate_class_type_arguments('>')
def __gt__(self, maya_dt):
return self._epoch > maya_dt._epoch
@validate_class_type_arguments('>=')
def __ge__(self, maya_dt):
return self._epoch >= maya_dt._epoch
# Timezone Crap
# -------------
@property
def timezone(self):
"""Returns the UTC tzinfo name. It's always UTC. Always."""
return 'UTC'
@property
def _tz(self):
"""Returns the UTC tzinfo object."""
return pytz.timezone(self.timezone)
@property
def local_timezone(self):
"""Returns the name of the local timezone, for informational purposes."""
return self._local_tz.zone
@property
def _local_tz(self):
"""Returns the local timezone."""
return get_localzone()
@staticmethod
def __dt_to_epoch(dt):
"""Converts a datetime into an epoch."""
# Assume UTC if no datetime is provided.
if dt.tzinfo is None:
dt = dt.replace(tzinfo=pytz.utc)
epoch_start = Datetime(*_EPOCH_START, tzinfo=pytz.timezone('UTC'))
return (dt - epoch_start).total_seconds()
# Importers
# ---------
@classmethod
def from_datetime(klass, dt):
"""Returns MayaDT instance from datetime."""
return klass(klass.__dt_to_epoch(dt))
@classmethod
def from_iso8601(klass, string):
"""Returns MayaDT instance from iso8601 string."""
dt = iso8601.parse_date(string)
return klass.from_datetime(dt)
@staticmethod
def from_rfc2822(string):
"""Returns MayaDT instance from rfc2822 string."""
return parse(string)
# Exporters
# ---------
def datetime(self, to_timezone=None, naive=False):
"""Returns a timezone-aware datetime...
Defaulting to UTC (as it should).
Keyword Arguments:
to_timezone {string} -- timezone to convert to (default: None/UTC)
naive {boolean} -- if True, the tzinfo is simply dropped (default: False)
"""
if to_timezone:
dt = self.datetime().astimezone(pytz.timezone(to_timezone))
else:
dt = Datetime.utcfromtimestamp(self._epoch)
dt.replace(tzinfo=self._tz)
# Strip the timezone info if requested to do so.
if naive:
return dt.replace(tzinfo=None)
else:
if dt.tzinfo is None:
dt = dt.replace(tzinfo=self._tz)
return dt
def iso8601(self):
"""Returns an ISO 8601 representation of the MayaDT."""
# Get a timezone-naive datetime.
dt = self.datetime(naive=True)
return '{}Z'.format(dt.isoformat())
def rfc2822(self):
"""Returns an RFC 2822 representation of the MayaDT."""
return email.utils.formatdate(self.epoch, usegmt=True)
# Properties
# ----------
@property
def year(self):
return self.datetime().year
@property
def month(self):
return self.datetime().month
@property
def day(self):
return self.datetime().day
@property
def week(self):
return self.datetime().isocalendar()[1]
@property
def weekday(self):
"""Return the day of the week as an integer. Monday is 1 and Sunday is 7"""
return self.datetime().isoweekday()
@property
def hour(self):
return self.datetime().hour
@property
def minute(self):
return self.datetime().minute
@property
def second(self):
return self.datetime().second
@property
def microsecond(self):
return self.datetime().microsecond
@property
def epoch(self):
return self._epoch
# Human Slang Extras
# ------------------
def slang_date(self):
""""Returns human slang representation of date."""
dt = self.datetime(naive=True, to_timezone=self.local_timezone)
return humanize.naturaldate(dt)
def slang_time(self):
""""Returns human slang representation of time."""
dt = self.datetime(naive=True, to_timezone=self.local_timezone)
return humanize.naturaltime(dt)
def now():
"""Returns a MayaDT instance for this exact moment."""
epoch = time.time()
return MayaDT(epoch=epoch)
def when(string, timezone='UTC'):
""""Returns a MayaDT instance for the human moment specified.
Powered by dateparser. Useful for scraping websites.
Examples:
'next week', 'now', 'tomorrow', '300 years ago', 'August 14, 2015'
Keyword Arguments:
string -- string to be parsed
timezone -- timezone referenced from (default: 'UTC')
"""
dt = dateparser.parse(string, settings={'TIMEZONE': timezone, 'RETURN_AS_TIMEZONE_AWARE': True, 'TO_TIMEZONE': 'UTC'})
if dt is None:
raise ValueError('invalid datetime input specified.')
return MayaDT.from_datetime(dt)
def parse(string, day_first=False):
""""Returns a MayaDT instance for the machine-produced moment specified.
Powered by dateutil. Accepts most known formats. Useful for working with data.
Keyword Arguments:
string -- string to be parsed
day_first -- if true, the first value (e.g. 01/05/2016) is parsed as day (default: False)
"""
dt = dateutil.parser.parse(string, dayfirst=day_first)
return MayaDT.from_datetime(dt)
+51
View File
@@ -0,0 +1,51 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import sys
import codecs
from setuptools import setup
try:
# Python 3
from os import dirname
except ImportError:
# Python 2
from os.path import dirname
here = os.path.abspath(dirname(__file__))
with codecs.open(os.path.join(here, 'README.rst'), encoding='utf-8') as f:
long_description = '\n' + f.read()
if sys.argv[-1] == "publish":
os.system("python setup.py sdist bdist_wheel upload")
sys.exit()
required = [
'humanize',
'pytz',
'dateparser',
'iso8601',
'python-dateutil',
'ruamel.yaml',
'tzlocal'
]
setup(
name='maya',
version='0.1.6',
description='Datetimes for Humans.',
long_description=long_description,
author='Kenneth Reitz',
author_email='me@kennethreitz.com',
url='https://github.com/kennethreitz/maya',
py_modules=['maya'],
install_requires=required,
license='MIT',
classifiers=(
),
)
Executable
+99
View File
@@ -0,0 +1,99 @@
#!/usr/bin/env bash
testNoRequirements() {
compile "no-requirements"
assertCapturedError
}
testSetupPy() {
compile "setup-py"
assertCaptured "maya"
assertCapturedSuccess
}
testStandardRequirements() {
compile "requirements-standard"
assertCaptured "requests"
assertCapturedSuccess
}
testPsycopg2() {
compile "psycopg2"
assertCaptured "psycopg2"
assertCapturedSuccess
}
testPython2() {
compile "python2"
assertCaptured "python-2.7.13"
assertCapturedSuccess
}
testPython3() {
compile "python3"
assertCaptured "python-3.6.0"
assertCapturedSuccess
}
pushd $(dirname 0) >/dev/null
popd >/dev/null
source $(pwd)/test/utils
mktmpdir() {
dir=$(mktemp -t testXXXXX)
rm -rf $dir
mkdir $dir
echo $dir
}
detect() {
capture $(pwd)/bin/detect $(pwd)/test/fixtures/$1
}
compile_dir=""
default_process_types_cleanup() {
file="/tmp/default_process_types"
if [ -f "$file" ]; then
rm "$file"
fi
}
compile() {
default_process_types_cleanup
bp_dir=$(mktmpdir)
compile_dir=$(mktmpdir)
cp -a $(pwd)/* ${bp_dir}
cp -a ${bp_dir}/test/fixtures/$1/. ${compile_dir}
capture ${bp_dir}/bin/compile ${compile_dir} ${2:-$(mktmpdir)} $3
}
compileDir() {
default_process_types_cleanup
local bp_dir=$(mktmpdir)
local compile_dir=${1:-$(mktmpdir)}
local cache_dir=${2:-$(mktmpdir)}
local env_dir=$3
cp -a $(pwd)/* ${bp_dir}
capture ${bp_dir}/bin/compile ${compile_dir} ${cache_dir} ${env_dir}
}
release() {
bp_dir=$(mktmpdir)
cp -a $(pwd)/* ${bp_dir}
capture ${bp_dir}/bin/release ${bp_dir}/test/fixtures/$1
}
assertFile() {
assertEquals "$1" "$(cat ${compile_dir}/$2)"
}
source $(pwd)/test/shunit2
Executable
+1048
View File
File diff suppressed because it is too large Load Diff
+195
View File
@@ -0,0 +1,195 @@
#!/bin/sh
# taken from
# https://github.com/ryanbrainard/heroku-buildpack-testrunner/blob/master/lib/test_utils.sh
oneTimeSetUp()
{
TEST_SUITE_CACHE="$(mktemp -d ${SHUNIT_TMPDIR}/test_suite_cache.XXXX)"
}
oneTimeTearDown()
{
rm -rf ${TEST_SUITE_CACHE}
}
setUp()
{
OUTPUT_DIR="$(mktemp -d ${SHUNIT_TMPDIR}/output.XXXX)"
STD_OUT="${OUTPUT_DIR}/stdout"
STD_ERR="${OUTPUT_DIR}/stderr"
BUILD_DIR="${OUTPUT_DIR}/build"
CACHE_DIR="${OUTPUT_DIR}/cache"
mkdir -p ${OUTPUT_DIR}
mkdir -p ${BUILD_DIR}
mkdir -p ${CACHE_DIR}
}
tearDown()
{
rm -rf ${OUTPUT_DIR}
}
capture()
{
resetCapture
LAST_COMMAND="$@"
$@ >${STD_OUT} 2>${STD_ERR}
RETURN=$?
rtrn=${RETURN} # deprecated
}
resetCapture()
{
if [ -f ${STD_OUT} ]; then
rm ${STD_OUT}
fi
if [ -f ${STD_ERR} ]; then
rm ${STD_ERR}
fi
unset LAST_COMMAND
unset RETURN
unset rtrn # deprecated
}
detect()
{
capture ${BUILDPACK_HOME}/bin/detect ${BUILD_DIR}
}
compile()
{
capture ${BUILDPACK_HOME}/bin/compile ${BUILD_DIR} ${CACHE_DIR}
}
release()
{
capture ${BUILDPACK_HOME}/bin/release ${BUILD_DIR}
}
assertCapturedEquals()
{
assertEquals "$@" "$(cat ${STD_OUT})"
}
assertCapturedNotEquals()
{
assertNotEquals "$@" "$(cat ${STD_OUT})"
}
assertCaptured()
{
assertFileContains "$@" "${STD_OUT}"
}
assertNotCaptured()
{
assertFileNotContains "$@" "${STD_OUT}"
}
assertCapturedSuccess()
{
assertEquals "Expected captured exit code to be 0; was <${RETURN}>" "0" "${RETURN}"
assertEquals "Expected STD_ERR to be empty; was <$(cat ${STD_ERR})>" "" "$(cat ${STD_ERR})"
}
# assertCapturedError [[expectedErrorCode] expectedErrorMsg]
assertCapturedError()
{
if [ $# -gt 1 ]; then
local expectedErrorCode=${1}
shift
fi
local expectedErrorMsg=${1:-""}
if [ -z ${expectedErrorCode} ]; then
assertTrue "Expected captured exit code to be greater than 0; was <${RETURN}>" "[ ${RETURN} -gt 0 ]"
else
assertTrue "Expected captured exit code to be <${expectedErrorCode}>; was <${RETURN}>" "[ ${RETURN} -eq ${expectedErrorCode} ]"
fi
if [ "${expectedErrorMsg}" != "" ]; then
assertFileContains "Expected STD_ERR to contain error <${expectedErrorMsg}>" "${expectedErrorMsg}" "${STD_ERR}"
fi
}
_assertContains()
{
if [ 5 -eq $# ]; then
local msg=$1
shift
elif [ ! 4 -eq $# ]; then
fail "Expected 4 or 5 parameters; Receieved $# parameters"
fi
local needle=$1
local haystack=$2
local expectation=$3
local haystack_type=$4
case "${haystack_type}" in
"file") grep -q -F -e "${needle}" ${haystack} ;;
"text") echo "${haystack}" | grep -q -F -e "${needle}" ;;
esac
if [ "${expectation}" != "$?" ]; then
case "${expectation}" in
0) default_msg="Expected <${haystack}> to contain <${needle}>" ;;
1) default_msg="Did not expect <${haystack}> to contain <${needle}>" ;;
esac
fail "${msg:-${default_msg}}"
fi
}
debug()
{
cat $STD_OUT
}
assertContains()
{
_assertContains "$@" 0 "text"
}
assertNotContains()
{
_assertContains "$@" 1 "text"
}
assertFileContains()
{
_assertContains "$@" 0 "file"
}
assertFileNotContains()
{
_assertContains "$@" 1 "file"
}
command_exists () {
type "$1" > /dev/null 2>&1 ;
}
assertFileMD5()
{
expectedHash=$1
filename=$2
if command_exists "md5sum"; then
md5_cmd="md5sum ${filename}"
expected_md5_cmd_output="${expectedHash} ${filename}"
elif command_exists "md5"; then
md5_cmd="md5 ${filename}"
expected_md5_cmd_output="MD5 (${filename}) = ${expectedHash}"
else
fail "no suitable MD5 hashing command found on this system"
fi
assertEquals "${expected_md5_cmd_output}" "`${md5_cmd}`"
}
Executable
+16
View File
@@ -0,0 +1,16 @@
#!/usr/bin/env bash
if [[ ! "$STACK" ]]; then
echo '$STACK must be set! (heroku-16 | cedar-14)'
exit 1
fi
if [[ "$STACK" == "cedar-14" ]]; then
make test-cedar-14
exit $?
fi
if [[ "$STACK" == "heroku-16" ]]; then
make test-heroku-16
exit $?
fi
Vendored Executable
BIN
View File
Binary file not shown.
Vendored Executable
+15
View File
@@ -0,0 +1,15 @@
#!/usr/bin/env python
import sys
req_file = sys.argv[1]
lines = []
with open(req_file, 'r') as f:
r = f.readlines()
for l in r:
lines.append(l.split('--hash')[0])
with open(req_file, 'w') as f:
f.write('\n'.join(lines))
+11 -5
View File
@@ -1,32 +1,38 @@
if [[ "${WEB_CONCURRENCY:-}" == 0* ]]; then
# another buildpack set a default value, with leading zero
unset WEB_CONCURRENCY
fi
case $(ulimit -u) in case $(ulimit -u) in
# Automatic configuration for Gunicorn's Workers setting. # Automatic configuration for Gunicorn's Workers setting.
# Leading zero padding so a subsequent buildpack can figure out that we set a value, and not the user
# Standard-1X (+Free, +Hobby) Dyno # Standard-1X (+Free, +Hobby) Dyno
256) 256)
export DYNO_RAM=512 export DYNO_RAM=512
export WEB_CONCURRENCY=${WEB_CONCURRENCY:-2} export WEB_CONCURRENCY=${WEB_CONCURRENCY:-02}
;; ;;
# Standard-2X Dyno # Standard-2X Dyno
512) 512)
export DYNO_RAM=1024 export DYNO_RAM=1024
export WEB_CONCURRENCY=${WEB_CONCURRENCY:-4} export WEB_CONCURRENCY=${WEB_CONCURRENCY:-04}
;; ;;
# Performance-M Dyno # Performance-M Dyno
16384) 16384)
export DYNO_RAM=2560 export DYNO_RAM=2560
export WEB_CONCURRENCY=${WEB_CONCURRENCY:-8} export WEB_CONCURRENCY=${WEB_CONCURRENCY:-08}
;; ;;
# Performance-L Dyno # Performance-L Dyno
32768) 32768)
export DYNO_RAM=6656 export DYNO_RAM=6656
export WEB_CONCURRENCY=${WEB_CONCURRENCY:-11} export WEB_CONCURRENCY=${WEB_CONCURRENCY:-011}
;; ;;
esac esac
# Automatic configuration for Gunicorn's ForwardedAllowIPS setting. # Automatic configuration for Gunicorn's ForwardedAllowIPS setting.
export FORWARDED_ALLOW_IPS='*' export FORWARDED_ALLOW_IPS='*'