mirror of
https://github.com/LukeHagar/pypistats.org.git
synced 2025-12-06 04:21:09 +00:00
docker setup; celery/beat config
This commit is contained in:
35
.dockerignore
Normal file
35
.dockerignore
Normal file
@@ -0,0 +1,35 @@
|
||||
# project
|
||||
.git
|
||||
.gitignore
|
||||
.dockerignore
|
||||
Dockerfile
|
||||
Pipfile
|
||||
Pipfile.lock
|
||||
migrations/
|
||||
zappa*
|
||||
run.sh
|
||||
docs/
|
||||
tests/
|
||||
|
||||
# mac osx
|
||||
.DS_Store
|
||||
|
||||
# python bytecode
|
||||
*.py[cod]
|
||||
__pycache__
|
||||
|
||||
# ignore
|
||||
ignore/
|
||||
|
||||
# celery
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# redis
|
||||
dump.rdb
|
||||
|
||||
# packaged deployments
|
||||
*.zip
|
||||
|
||||
# zappa settings
|
||||
zappa_settings.json
|
||||
8
.gitignore
vendored
8
.gitignore
vendored
@@ -1,4 +1,3 @@
|
||||
|
||||
# credentials
|
||||
secret.*
|
||||
env_vars*
|
||||
@@ -16,5 +15,12 @@ ignore/
|
||||
# packaged deployments
|
||||
*.zip
|
||||
|
||||
# celery
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# redis
|
||||
dump.rdb
|
||||
|
||||
# zappa settings
|
||||
zappa_settings.json
|
||||
|
||||
7
Dockerfile
Normal file
7
Dockerfile
Normal file
@@ -0,0 +1,7 @@
|
||||
FROM python:3.6-slim
|
||||
|
||||
ADD requirements.txt requirements.txt
|
||||
RUN pip install -r requirements.txt
|
||||
ADD . .
|
||||
|
||||
EXPOSE 5000
|
||||
15
Pipfile
15
Pipfile
@@ -10,13 +10,14 @@ name = "pypi"
|
||||
google-cloud-bigquery = "*"
|
||||
pandas = "*"
|
||||
"psycopg2" = "*"
|
||||
Flask = "*"
|
||||
GitHub-Flask = "*"
|
||||
Flask-SQLAlchemy = "*"
|
||||
Flask-Migrate = "*"
|
||||
Flask-Login = "*"
|
||||
Flask-WTF = "*"
|
||||
zappa = "*"
|
||||
flask = "*"
|
||||
github-flask = "*"
|
||||
flask-sqlalchemy = "*"
|
||||
flask-migrate = "*"
|
||||
flask-login = "*"
|
||||
flask-wtf = "*"
|
||||
celery = "*"
|
||||
redis = "*"
|
||||
|
||||
|
||||
[dev-packages]
|
||||
|
||||
219
Pipfile.lock
generated
219
Pipfile.lock
generated
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "f00e05278f16f93aec905d0408ca9e786385d8f3a2a29dc5a1b7b6b65aca8383"
|
||||
"sha256": "8fbdf096ac477c3d82ab03aa50f0238201297c7572dc9d7b5f709675e7f0e6bd"
|
||||
},
|
||||
"host-environment-markers": {
|
||||
"implementation_name": "cpython",
|
||||
@@ -33,33 +33,19 @@
|
||||
],
|
||||
"version": "==0.9.9"
|
||||
},
|
||||
"argcomplete": {
|
||||
"amqp": {
|
||||
"hashes": [
|
||||
"sha256:74e34bbd5bcb902e67a39e2edf1b1ef3dcb504a6a1d4cd23ce3949f25c4aad55",
|
||||
"sha256:d6ea272a93bb0387f758def836e73c36fff0c54170258c212de3e84f7db8d5ed"
|
||||
"sha256:4e28d3ea61a64ae61830000c909662cb053642efddbe96503db0e7783a6ee85b",
|
||||
"sha256:cba1ace9d4ff6049b190d8b7991f9c1006b443a5238021aca96dd6ad2ac9da22"
|
||||
],
|
||||
"version": "==1.9.2"
|
||||
"version": "==2.2.2"
|
||||
},
|
||||
"base58": {
|
||||
"billiard": {
|
||||
"hashes": [
|
||||
"sha256:aafdd84adf1fbd073eb2fd7f7266d7bd9f2423ee1000ee61cd021b97ed359f39",
|
||||
"sha256:97cb4dcbc7a81afb802f41033d5562b6c48633426a67bf41e4cad186f581158c"
|
||||
"sha256:abd9ce008c9a71ccde2c816f8daa36246e92a21e6a799831b887d88277187ecd",
|
||||
"sha256:1d7b22bdc47aa52841120fcd22a74ae4fc8c13e9d3935643098184f5788c3ce6"
|
||||
],
|
||||
"version": "==0.2.4"
|
||||
},
|
||||
"boto3": {
|
||||
"hashes": [
|
||||
"sha256:13ad5f64a247d655a27dca83274588e9d14cba61b38d3d4fd2b011b7197d88dd",
|
||||
"sha256:a56b21efbc994580fc9cef454f0f949745c152326f939aed6609d1c47b2a0f8f"
|
||||
],
|
||||
"version": "==1.7.4"
|
||||
},
|
||||
"botocore": {
|
||||
"hashes": [
|
||||
"sha256:77f2869b8c27afbab78b72ce6b74c75923421f364c7a0153ac1a38858c59cd91",
|
||||
"sha256:5602738392ecde5c02a06a3b02de07171f440a44cdfef0aadff4b59567359607"
|
||||
],
|
||||
"version": "==1.10.4"
|
||||
"version": "==3.5.0.3"
|
||||
},
|
||||
"cachetools": {
|
||||
"hashes": [
|
||||
@@ -68,18 +54,19 @@
|
||||
],
|
||||
"version": "==2.0.1"
|
||||
},
|
||||
"celery": {
|
||||
"hashes": [
|
||||
"sha256:81a67f0d53a688ec2bc8557bd5d6d7218f925a6f2e6df80e01560de9e28997ec",
|
||||
"sha256:77ff3730198d6a17b3c1f05579ebe570b579efb35f6d7e13dba3b1368d068b35"
|
||||
],
|
||||
"version": "==4.1.0"
|
||||
},
|
||||
"certifi": {
|
||||
"hashes": [
|
||||
"sha256:14131608ad2fd56836d33a71ee60fa1c82bc9d2c8d98b7bdbc631fe1b3cd1296",
|
||||
"sha256:edbc3f203427eef571f79a7692bb160a2b0f7ccaa31953e99bd17e307cf63f7d"
|
||||
"sha256:9fa520c1bacfb634fa7af20a76bcbd3d5fb390481724c597da32c719a7dca4b0",
|
||||
"sha256:13e698f54293db9f89122b0581843a782ad0934a4fe0172d2a980ba77fc61bb7"
|
||||
],
|
||||
"version": "==2018.1.18"
|
||||
},
|
||||
"cfn-flip": {
|
||||
"hashes": [
|
||||
"sha256:9c61039c71995ab204c005ec46d47d0f7a109e9f1b6d63569397f8bc648a8151"
|
||||
],
|
||||
"version": "==1.0.3"
|
||||
"version": "==2018.4.16"
|
||||
},
|
||||
"chardet": {
|
||||
"hashes": [
|
||||
@@ -95,20 +82,6 @@
|
||||
],
|
||||
"version": "==6.7"
|
||||
},
|
||||
"docutils": {
|
||||
"hashes": [
|
||||
"sha256:7a4bd47eaf6596e1295ecb11361139febe29b084a87bf005bf899f9a42edc3c6",
|
||||
"sha256:02aec4bd92ab067f6ff27a38a38a41173bf01bed8f89157768c1573f53e474a6",
|
||||
"sha256:51e64ef2ebfb29cae1faa133b3710143496eca21c530f3f71424d77687764274"
|
||||
],
|
||||
"version": "==0.14"
|
||||
},
|
||||
"durationpy": {
|
||||
"hashes": [
|
||||
"sha256:5ef9416b527b50d722f34655becfb75e49228eb82f87b855ed1911b3314b5408"
|
||||
],
|
||||
"version": "==0.5"
|
||||
},
|
||||
"flask": {
|
||||
"hashes": [
|
||||
"sha256:0749df235e3ff61ac108f69ac178c9770caeaccad2509cb762ce1f65570a8856",
|
||||
@@ -143,12 +116,6 @@
|
||||
],
|
||||
"version": "==0.14.2"
|
||||
},
|
||||
"future": {
|
||||
"hashes": [
|
||||
"sha256:e39ced1ab767b5936646cedba8bcce582398233d6a627067d4c6a454c90cfedb"
|
||||
],
|
||||
"version": "==0.16.0"
|
||||
},
|
||||
"github-flask": {
|
||||
"hashes": [
|
||||
"sha256:24600b720f698bac10667b76b136995ba7821d884e58b27e2a18ca0e4760c786"
|
||||
@@ -157,10 +124,10 @@
|
||||
},
|
||||
"google-api-core": {
|
||||
"hashes": [
|
||||
"sha256:7618a9c2ee84c0d99f9c7823675c15024b25094bb920f49d204a72107d856aac",
|
||||
"sha256:b4f103de6bd38ab346f7d17236f6098a51ebdff733ff69956a0f1e29cb35f10b"
|
||||
"sha256:4885e5298e45aa587185c32bee54f95e79a05a926d69fcfd398c66b12b98b9a7",
|
||||
"sha256:d23d5ae89e44ca1ddddec94e5f7c03f52402d192e66345d448b77ad5276b0fbe"
|
||||
],
|
||||
"version": "==1.1.0"
|
||||
"version": "==1.1.1"
|
||||
},
|
||||
"google-auth": {
|
||||
"hashes": [
|
||||
@@ -171,10 +138,10 @@
|
||||
},
|
||||
"google-cloud-bigquery": {
|
||||
"hashes": [
|
||||
"sha256:0681c20dbc663ba382397fd4fc45bd6dba92339408ff399365e47303753f3084",
|
||||
"sha256:f1c274342a364904de0656eeee519ba6c2cf165204b824ccb39370b72f242894"
|
||||
"sha256:44d152e1de60cce8fe9d4f5c60ca4cebc88daab02b4d889bb0ebfcc19d54d7ec",
|
||||
"sha256:aed2b1d4db1e21d891522d6d6bb14476e6ba58c681cbb68eeb42c168a4e3fda9"
|
||||
],
|
||||
"version": "==0.32.0"
|
||||
"version": "==1.1.0"
|
||||
},
|
||||
"google-cloud-core": {
|
||||
"hashes": [
|
||||
@@ -196,12 +163,6 @@
|
||||
],
|
||||
"version": "==1.5.3"
|
||||
},
|
||||
"hjson": {
|
||||
"hashes": [
|
||||
"sha256:1d1727faa6aaef2973921877125a3ab7c5f6d34b93233179d01770f41fab51f9"
|
||||
],
|
||||
"version": "==3.0.1"
|
||||
},
|
||||
"idna": {
|
||||
"hashes": [
|
||||
"sha256:8c7309c718f94b3a625cb648ace320157ad16ff131ae0af362c9f21b80ef6ec4",
|
||||
@@ -222,25 +183,12 @@
|
||||
],
|
||||
"version": "==2.10"
|
||||
},
|
||||
"jmespath": {
|
||||
"kombu": {
|
||||
"hashes": [
|
||||
"sha256:f11b4461f425740a1d908e9a3f7365c3d2e569f6ca68a2ff8bc5bcd9676edd63",
|
||||
"sha256:6a81d4c9aa62caf061cb517b4d9ad1dd300374cd4706997aff9cd6aedd61fc64"
|
||||
"sha256:01f0da9fe222a2183345004243d1518c0fbe5875955f1b24842f2d9c65709ade",
|
||||
"sha256:4249d9dd9dbf1fcec471d1c2def20653c9310dd1a217272d77e4844f9d5273cb"
|
||||
],
|
||||
"version": "==0.9.3"
|
||||
},
|
||||
"kappa": {
|
||||
"hashes": [
|
||||
"sha256:4d6b7b3accce4a0aaaac92b36237a6304f0f2fffbbe3caea3f7c9f52d12c9989",
|
||||
"sha256:4b5b372872f25d619e427e04282551048dc975a107385b076b3ffc6406a15833"
|
||||
],
|
||||
"version": "==0.6.0"
|
||||
},
|
||||
"lambda-packages": {
|
||||
"hashes": [
|
||||
"sha256:cbe35f0642206a4adfb4855f80d55e273bdacc083011eba5f9ed3beedf0879fa"
|
||||
],
|
||||
"version": "==0.19.0"
|
||||
"version": "==4.1.0"
|
||||
},
|
||||
"mako": {
|
||||
"hashes": [
|
||||
@@ -302,12 +250,6 @@
|
||||
],
|
||||
"version": "==0.22.0"
|
||||
},
|
||||
"placebo": {
|
||||
"hashes": [
|
||||
"sha256:8aa848b892924786fa5e37e75524e8ec039b7d54860d35c51ffb4ed3e30590c5"
|
||||
],
|
||||
"version": "==0.8.1"
|
||||
},
|
||||
"protobuf": {
|
||||
"hashes": [
|
||||
"sha256:ac0067e3c60737865ed72bb7416e02297d229d960902802d874c0e167128c809",
|
||||
@@ -401,10 +343,10 @@
|
||||
},
|
||||
"python-dateutil": {
|
||||
"hashes": [
|
||||
"sha256:95511bae634d69bc7329ba55e646499a842bc4ec342ad54a8cdb65645a0aad3c",
|
||||
"sha256:891c38b2a02f5bb1be3e4793866c8df49c7d19baabf9c1bad62547e0b4866aca"
|
||||
"sha256:3220490fb9741e2342e1cf29a503394fdac874bc39568288717ee67047ff29df",
|
||||
"sha256:9d8074be4c993fbe4947878ce593052f71dac82932a677d49194d8ce9778002e"
|
||||
],
|
||||
"version": "==2.6.1"
|
||||
"version": "==2.7.2"
|
||||
},
|
||||
"python-editor": {
|
||||
"hashes": [
|
||||
@@ -412,13 +354,6 @@
|
||||
],
|
||||
"version": "==1.0.3"
|
||||
},
|
||||
"python-slugify": {
|
||||
"hashes": [
|
||||
"sha256:c3733135d3b184196fdb8844f6a74bbfb9cf6720d1dcce3254bdc434353f938f",
|
||||
"sha256:57a385df7a1c6dbd15f7666eaff0ff29d3f60363b228b1197c5308ed3ba5f824"
|
||||
],
|
||||
"version": "==1.2.4"
|
||||
},
|
||||
"pytz": {
|
||||
"hashes": [
|
||||
"sha256:65ae0c8101309c45772196b21b74c46b2e5d11b6275c45d251b150d5da334555",
|
||||
@@ -426,24 +361,12 @@
|
||||
],
|
||||
"version": "==2018.4"
|
||||
},
|
||||
"pyyaml": {
|
||||
"redis": {
|
||||
"hashes": [
|
||||
"sha256:3262c96a1ca437e7e4763e2843746588a965426550f3797a79fca9c6199c431f",
|
||||
"sha256:16b20e970597e051997d90dc2cddc713a2876c47e3d92d59ee198700c5427736",
|
||||
"sha256:e863072cdf4c72eebf179342c94e6989c67185842d9997960b3e69290b2fa269",
|
||||
"sha256:bc6bced57f826ca7cb5125a10b23fd0f2fff3b7c4701d64c439a300ce665fff8",
|
||||
"sha256:c01b880ec30b5a6e6aa67b09a2fe3fb30473008c85cd6a67359a1b15ed6d83a4",
|
||||
"sha256:827dc04b8fa7d07c44de11fabbc888e627fa8293b695e0f99cb544fdfa1bf0d1",
|
||||
"sha256:592766c6303207a20efc445587778322d7f73b161bd994f227adaa341ba212ab",
|
||||
"sha256:5f84523c076ad14ff5e6c037fe1c89a7f73a3e04cf0377cb4d017014976433f3",
|
||||
"sha256:0c507b7f74b3d2dd4d1322ec8a94794927305ab4cebbe89cc47fe5e81541e6e8",
|
||||
"sha256:b4c423ab23291d3945ac61346feeb9a0dc4184999ede5e7c43e1ffb975130ae6",
|
||||
"sha256:ca233c64c6e40eaa6c66ef97058cdc80e8d0157a443655baa1b2966e812807ca",
|
||||
"sha256:4474f8ea030b5127225b8894d626bb66c01cda098d47a2b0d3429b6700af9fd8",
|
||||
"sha256:326420cbb492172dec84b0f65c80942de6cedb5233c413dd824483989c000608",
|
||||
"sha256:5ac82e411044fb129bae5cfbeb3ba626acb2af31a8d17d175004b70862a741a7"
|
||||
"sha256:8a1900a9f2a0a44ecf6e8b5eb3e967a9909dfed219ad66df094f27f7d6f330fb",
|
||||
"sha256:a22ca993cea2962dbb588f9f30d0015ac4afcc45bee27d3978c0dbe9e97c6c0f"
|
||||
],
|
||||
"version": "==3.12"
|
||||
"version": "==2.10.6"
|
||||
},
|
||||
"requests": {
|
||||
"hashes": [
|
||||
@@ -459,13 +382,6 @@
|
||||
],
|
||||
"version": "==3.4.2"
|
||||
},
|
||||
"s3transfer": {
|
||||
"hashes": [
|
||||
"sha256:c7a9ec356982d5e9ab2d4b46391a7d6a950e2b04c472419f5fdec70cc0ada72f",
|
||||
"sha256:90dc18e028989c609146e241ea153250be451e05ecc0c2832565231dacdf59c1"
|
||||
],
|
||||
"version": "==0.1.13"
|
||||
},
|
||||
"six": {
|
||||
"hashes": [
|
||||
"sha256:832dc0e10feb1aa2c68dcc57dbb658f1c7e65b9b61af69048abc87a2db00a0eb",
|
||||
@@ -475,35 +391,9 @@
|
||||
},
|
||||
"sqlalchemy": {
|
||||
"hashes": [
|
||||
"sha256:7cb00cc9b9f92ef8b4391c8a2051f81eeafefe32d63c6b395fd51401e9a39edb"
|
||||
"sha256:d6cda03b0187d6ed796ff70e87c9a7dce2c2c9650a7bc3c022cd331416853c31"
|
||||
],
|
||||
"version": "==1.2.6"
|
||||
},
|
||||
"toml": {
|
||||
"hashes": [
|
||||
"sha256:8e86bd6ce8cc11b9620cb637466453d94f5d57ad86f17e98a98d1f73e3baab2d"
|
||||
],
|
||||
"version": "==0.9.4"
|
||||
},
|
||||
"tqdm": {
|
||||
"hashes": [
|
||||
"sha256:ba650e08b8b102923a05896bf9d7e1c9cdc20b484156df0511a4bbf1f6b6f89b",
|
||||
"sha256:fa6d2ea6285f56e75d7efe9259805deadc450f16066a1f82ad0629ea9be2cd0f"
|
||||
],
|
||||
"version": "==4.19.1"
|
||||
},
|
||||
"troposphere": {
|
||||
"hashes": [
|
||||
"sha256:e15e2470fe4f02a5c1b70ccd552b09ac664acfff0de74cd4464acf8e6039e118"
|
||||
],
|
||||
"version": "==2.2.1"
|
||||
},
|
||||
"unidecode": {
|
||||
"hashes": [
|
||||
"sha256:72f49d3729f3d8f5799f710b97c1451c5163102e76d64d20e170aedbbd923582",
|
||||
"sha256:8c33dd588e0c9bc22a76eaa0c715a5434851f726131bd44a6c26471746efabf5"
|
||||
],
|
||||
"version": "==1.0.22"
|
||||
"version": "==1.2.7"
|
||||
},
|
||||
"urllib3": {
|
||||
"hashes": [
|
||||
@@ -512,38 +402,25 @@
|
||||
],
|
||||
"version": "==1.22"
|
||||
},
|
||||
"vine": {
|
||||
"hashes": [
|
||||
"sha256:6849544be74ec3638e84d90bc1cf2e1e9224cc10d96cd4383ec3f69e9bce077b",
|
||||
"sha256:52116d59bc45392af9fdd3b75ed98ae48a93e822cee21e5fda249105c59a7a72"
|
||||
],
|
||||
"version": "==1.1.4"
|
||||
},
|
||||
"werkzeug": {
|
||||
"hashes": [
|
||||
"sha256:7fce5d96278e9e4132fd0e90ff17d2bcc6e74695d11e619ba4645c0341396810",
|
||||
"sha256:f007848ed997101cb5c09a47e46c0b0b6f193d0f8a01cd2af920d77bf1ab4e68"
|
||||
"sha256:d5da73735293558eb1651ee2fddc4d0dedcfa06538b8813a2e20011583c9e49b",
|
||||
"sha256:c3fd7a7d41976d9f44db327260e263132466836cef6f91512889ed60ad26557c"
|
||||
],
|
||||
"version": "==0.12"
|
||||
},
|
||||
"wheel": {
|
||||
"hashes": [
|
||||
"sha256:9cdc8ab2cc9c3c2e2727a4b67c22881dbb0e1c503d592992594c5e131c867107",
|
||||
"sha256:1ae8153bed701cb062913b72429bcf854ba824f973735427681882a688cb55ce"
|
||||
],
|
||||
"version": "==0.31.0"
|
||||
},
|
||||
"wsgi-request-logger": {
|
||||
"hashes": [
|
||||
"sha256:445d7ec52799562f812006394d0b4a7064b37084c6ea6bd74ea7a2136c97ed83"
|
||||
],
|
||||
"version": "==0.4.6"
|
||||
"version": "==0.14.1"
|
||||
},
|
||||
"wtforms": {
|
||||
"hashes": [
|
||||
"sha256:ffdf10bd1fa565b8233380cb77a304cd36fd55c73023e91d4b803c96bc11d46f"
|
||||
],
|
||||
"version": "==2.1"
|
||||
},
|
||||
"zappa": {
|
||||
"hashes": [
|
||||
"sha256:cf4654dfa7cd8777403ea2e379139b126c7e47943edb4e5441bb222a555a1aff",
|
||||
"sha256:827c2c1cc84790674476a98773601b924a2b4f3b0b81684571cd034326231158"
|
||||
],
|
||||
"version": "==0.45.1"
|
||||
}
|
||||
},
|
||||
"develop": {}
|
||||
|
||||
10
README.rst
10
README.rst
@@ -5,3 +5,13 @@ A simple analytics dashboard for aggregate data on PyPI downloads. PyPI Stats
|
||||
is built using Flask with plotly.js and deployed to AWS using Zappa.
|
||||
|
||||
`PyPI Stats <https://pypistats.org/>`_
|
||||
|
||||
Commands
|
||||
--------
|
||||
Beat:
|
||||
|
||||
pipenv run celery beat -A pypistats.run.celery --loglevel=INFO
|
||||
|
||||
Celery worker:
|
||||
|
||||
pipenv run celery -A pypistats.run.celery worker --loglevel=INFO
|
||||
|
||||
34
docker-compose.yaml
Normal file
34
docker-compose.yaml
Normal file
@@ -0,0 +1,34 @@
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
redis:
|
||||
image: 'redis:alpine'
|
||||
restart: always
|
||||
command: redis-server
|
||||
ports:
|
||||
- '6379:6379'
|
||||
|
||||
flask:
|
||||
build: .
|
||||
restart: always
|
||||
environment:
|
||||
- FLASK_APP=pypistats/run.py
|
||||
- ENV=prod
|
||||
command: 'flask run --host=0.0.0.0'
|
||||
ports:
|
||||
- '5000:5000'
|
||||
|
||||
celery:
|
||||
build: .
|
||||
restart: always
|
||||
command: 'celery -A pypistats.run.celery worker -l info'
|
||||
user: nobody
|
||||
depends_on:
|
||||
- redis
|
||||
|
||||
beat:
|
||||
build: .
|
||||
restart: always
|
||||
command: 'celery beat -A pypistats.run.celery -l info'
|
||||
depends_on:
|
||||
- redis
|
||||
@@ -1,4 +1,6 @@
|
||||
"""PyPIStats application."""
|
||||
from celery import Celery
|
||||
from celery import Task
|
||||
from flask import Flask
|
||||
|
||||
from pypistats import views
|
||||
@@ -9,22 +11,29 @@ from pypistats.settings import DevConfig
|
||||
|
||||
|
||||
def create_app(config_object=DevConfig):
|
||||
"""Create the application.
|
||||
|
||||
:param config_object: The configuration object to use.
|
||||
"""
|
||||
app = Flask(__name__.split('.')[0])
|
||||
"""Create the application."""
|
||||
app = Flask(__name__.split(".")[0])
|
||||
app.config.from_object(config_object)
|
||||
register_extensions(app)
|
||||
register_blueprints(app)
|
||||
return app
|
||||
|
||||
|
||||
def register_extensions(app):
|
||||
"""Register Flask extensions."""
|
||||
db.init_app(app)
|
||||
github.init_app(app)
|
||||
migrate.init_app(app, db)
|
||||
def create_celery(app):
|
||||
"""Create a celery object."""
|
||||
celery = Celery(app.import_name, broker=app.config["CELERY_BROKER_URL"])
|
||||
celery.conf.update(app.config)
|
||||
celery.config_from_object(app.config)
|
||||
|
||||
class ContextTask(Task):
|
||||
abstract = True
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
with app.app_context():
|
||||
return Task.__call__(self, *args, **kwargs)
|
||||
|
||||
celery.Task = ContextTask
|
||||
return celery
|
||||
|
||||
|
||||
def register_blueprints(app):
|
||||
@@ -33,3 +42,10 @@ def register_blueprints(app):
|
||||
app.register_blueprint(views.error.blueprint)
|
||||
app.register_blueprint(views.general.blueprint)
|
||||
app.register_blueprint(views.user.blueprint)
|
||||
|
||||
|
||||
def register_extensions(app):
|
||||
"""Register Flask extensions."""
|
||||
db.init_app(app)
|
||||
github.init_app(app)
|
||||
migrate.init_app(app, db)
|
||||
|
||||
@@ -41,13 +41,13 @@ class Model(CRUDMixin, db.Model):
|
||||
|
||||
|
||||
class SurrogatePK(object):
|
||||
"""A mixin that adds a surrogate integer 'primary key' column.
|
||||
"""A mixin that adds a surrogate integer "primary key" column.
|
||||
|
||||
Adds a surrogate integer 'primary key' column named ``id`` to any
|
||||
Adds a surrogate integer "primary key" column named ``id`` to any
|
||||
declarative-mapped class.
|
||||
"""
|
||||
|
||||
__table_args__ = {'extend_existing': True}
|
||||
__table_args__ = {"extend_existing": True}
|
||||
|
||||
id = Column(db.Integer, primary_key=True)
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ from flask import g
|
||||
from flask import session
|
||||
|
||||
from pypistats.application import create_app
|
||||
from pypistats.application import create_celery
|
||||
from pypistats.models.user import User
|
||||
from pypistats.settings import configs
|
||||
|
||||
@@ -12,8 +13,9 @@ from pypistats.settings import configs
|
||||
# change this for migrations
|
||||
env = os.environ.get("ENV", "dev")
|
||||
|
||||
|
||||
print(env)
|
||||
app = create_app(configs[env])
|
||||
celery = create_celery(app)
|
||||
|
||||
|
||||
@app.before_request
|
||||
@@ -21,4 +23,4 @@ def before_request():
|
||||
"""Execute before requests."""
|
||||
g.user = None
|
||||
if "user_id" in session:
|
||||
g.user = User.query.get(session['user_id'])
|
||||
g.user = User.query.get(session["user_id"])
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
import json
|
||||
import os
|
||||
|
||||
from celery.schedules import crontab
|
||||
|
||||
|
||||
# For local use.
|
||||
def load_env_vars(env="dev"):
|
||||
@@ -10,7 +12,7 @@ def load_env_vars(env="dev"):
|
||||
os.path.dirname(os.path.abspath(__file__)),
|
||||
"secret",
|
||||
f"env_vars_{env}.json")
|
||||
for key, value in json.load(open(local_path, 'r')).items():
|
||||
for key, value in json.load(open(local_path, "r")).items():
|
||||
os.environ[key] = value
|
||||
|
||||
|
||||
@@ -30,6 +32,14 @@ class Config(object):
|
||||
"""Base configuration."""
|
||||
|
||||
APP_DIR = os.path.abspath(os.path.dirname(__file__))
|
||||
CELERY_BROKER_URL = os.environ.get("CELERY_BROKER_URL"),
|
||||
CELERY_IMPORTS = ("pypistats.tasks.pypi")
|
||||
CELERYBEAT_SCHEDULE = {
|
||||
"update_db": {
|
||||
"task": "pypistats.tasks.pypi.etl",
|
||||
"schedule": crontab(hour=1, minute=0), # 1am UTC
|
||||
},
|
||||
}
|
||||
GITHUB_CLIENT_ID = os.environ.get("GITHUB_CLIENT_ID")
|
||||
GITHUB_CLIENT_SECRET = os.environ.get("GITHUB_CLIENT_SECRET")
|
||||
PROJECT_ROOT = os.path.abspath(os.path.join(APP_DIR, os.pardir))
|
||||
|
||||
@@ -11,6 +11,8 @@ import pandas as pd
|
||||
import psycopg2
|
||||
from psycopg2.extras import execute_values
|
||||
|
||||
from pypistats.run import celery
|
||||
|
||||
|
||||
# For local use.
|
||||
def load_env_vars(env="dev"):
|
||||
@@ -29,16 +31,6 @@ MIRRORS = ("bandersnatch", "z3c.pypimirror", "Artifactory", "devpi")
|
||||
# PyPI systems
|
||||
SYSTEMS = ("Windows", "Linux", "Darwin")
|
||||
|
||||
# BigQuery definitions
|
||||
DATASET_ID = "pypistats"
|
||||
TABLE_ID = "pypistats"
|
||||
SCHEMA = [
|
||||
bigquery.SchemaField("package", "STRING", mode="REQUIRED"),
|
||||
bigquery.SchemaField("category_label", "STRING", mode="REQUIRED"),
|
||||
bigquery.SchemaField("category", "STRING", mode="NULLABLE"),
|
||||
bigquery.SchemaField("downloads", "INTEGER", mode="NULLABLE"),
|
||||
]
|
||||
|
||||
# postgresql tables to update for __all__
|
||||
PSQL_TABLES = ["overall", "python_major", "python_minor", "system"]
|
||||
|
||||
@@ -69,63 +61,28 @@ def get_google_credentials():
|
||||
return credentials
|
||||
|
||||
|
||||
def get_daily_download_stats(event, context):
|
||||
def get_daily_download_stats(env="dev", date=None):
|
||||
"""Get daily download stats for pypi packages from BigQuery."""
|
||||
start = time.time()
|
||||
env = event["kwargs"]["env"]
|
||||
if os.environ.get("ENV", None) is None:
|
||||
load_env_vars(env)
|
||||
else:
|
||||
env = os.environ.get("ENV")
|
||||
job_config = bigquery.QueryJobConfig()
|
||||
credentials = get_google_credentials()
|
||||
bq_client = bigquery.Client(
|
||||
project=os.environ["GOOGLE_PROJECT_ID"],
|
||||
credentials=credentials
|
||||
)
|
||||
date = event["kwargs"].get("date", None)
|
||||
if date is None:
|
||||
date = str(datetime.date.today() - datetime.timedelta(days=1))
|
||||
|
||||
# # Prepare a reference to the new dataset
|
||||
# dataset_ref = bq_client.dataset(DATASET_ID)
|
||||
# dataset = bigquery.Dataset(dataset_ref)
|
||||
#
|
||||
# # Create the dataset
|
||||
# try:
|
||||
# dataset = bq_client.create_dataset(dataset)
|
||||
# except Conflict:
|
||||
# pass
|
||||
#
|
||||
# # Prepare a reference to the table
|
||||
# table_ref = dataset_ref.table(TABLE_ID)
|
||||
# table = bigquery.Table(table_ref, schema=SCHEMA)
|
||||
#
|
||||
# # Create the table
|
||||
# try:
|
||||
# table = bq_client.create_table(table)
|
||||
# except Conflict:
|
||||
# pass
|
||||
|
||||
# local = False
|
||||
# if env == "dev":
|
||||
# try:
|
||||
# print("Loading from csv...")
|
||||
# df = pd.read_csv("ignore/sample_data.csv", index_col=0)
|
||||
# print("Done.")
|
||||
# # print(set(df["category_label"].values))
|
||||
# # sys.exit()
|
||||
# local = True
|
||||
# except Exception:
|
||||
# print("Loading failed.")
|
||||
|
||||
# if not local:
|
||||
print("Querying BigQuery...")
|
||||
# Get and perform the query, writing to destination table
|
||||
print("Sending query to BigQuery...")
|
||||
query = get_query(date)
|
||||
print("Done.")
|
||||
# job_config.destination = table_ref
|
||||
# job_config.write_disposition = "WRITE_TRUNCATE"
|
||||
print("Sent.")
|
||||
query_job = bq_client.query(query, job_config=job_config)
|
||||
iterator = query_job.result()
|
||||
print("Downloading results.")
|
||||
rows = list(iterator)
|
||||
print(len(rows), "rows from gbq")
|
||||
|
||||
@@ -147,11 +104,9 @@ def get_daily_download_stats(event, context):
|
||||
"downloads",
|
||||
])
|
||||
|
||||
# # For local testing
|
||||
# df.to_csv("ignore/sample_data.csv")
|
||||
|
||||
results = update_db(df, env)
|
||||
print("Elapsed: " + str(time.time() - start))
|
||||
results["elapsed"] = time.time() - start
|
||||
return results
|
||||
|
||||
|
||||
@@ -174,9 +129,6 @@ def update_db(df, env="dev"):
|
||||
success[table] = update_table(
|
||||
connection, cursor, table, df_category, date
|
||||
)
|
||||
# update_all_package_stats(cursor, table, date)
|
||||
|
||||
# update_recent_stats(cursor, date)
|
||||
|
||||
return success
|
||||
|
||||
@@ -205,18 +157,18 @@ def update_table(connection, cursor, table, df, date):
|
||||
return False
|
||||
|
||||
|
||||
def update_all_package_stats(event, context):
|
||||
def update_all_package_stats(env="dev", date=None):
|
||||
"""Update stats for __all__ packages."""
|
||||
print("__all__")
|
||||
start = time.time()
|
||||
|
||||
date = event["kwargs"].get("date", None)
|
||||
if date is None:
|
||||
date = str(datetime.date.today() - datetime.timedelta(days=1))
|
||||
|
||||
env = event["kwargs"]["env"]
|
||||
if os.environ.get("ENV", None) is None:
|
||||
load_env_vars(env)
|
||||
else:
|
||||
env = os.environ.get("ENV")
|
||||
|
||||
connection, cursor = get_connection_cursor(env)
|
||||
|
||||
@@ -246,21 +198,22 @@ def update_all_package_stats(event, context):
|
||||
success[table] = False
|
||||
|
||||
print("Elapsed: " + str(time.time() - start))
|
||||
success["elapsed"] = time.time() - start
|
||||
return success
|
||||
|
||||
|
||||
def update_recent_stats(event, context):
|
||||
def update_recent_stats(env="dev", date=None):
|
||||
"""Update daily, weekly, monthly stats for all packages."""
|
||||
print("recent")
|
||||
start = time.time()
|
||||
|
||||
date = event["kwargs"].get("date", None)
|
||||
if date is None:
|
||||
date = str(datetime.date.today() - datetime.timedelta(days=1))
|
||||
|
||||
env = event["kwargs"]["env"]
|
||||
if os.environ.get("ENV", None) is None:
|
||||
load_env_vars(env)
|
||||
else:
|
||||
env = os.environ.get("ENV")
|
||||
|
||||
connection, cursor = get_connection_cursor(env)
|
||||
|
||||
@@ -305,6 +258,7 @@ def update_recent_stats(event, context):
|
||||
success[period] = False
|
||||
|
||||
print("Elapsed: " + str(time.time() - start))
|
||||
success["elapsed"] = time.time() - start
|
||||
return success
|
||||
|
||||
|
||||
@@ -322,19 +276,19 @@ def get_connection_cursor(env):
|
||||
return connection, cursor
|
||||
|
||||
|
||||
def purge_old_data(event, context):
|
||||
def purge_old_data(env="dev", date=None):
|
||||
"""Purge old data records."""
|
||||
print("Purge")
|
||||
age = MAX_RECORD_AGE
|
||||
start = time.time()
|
||||
|
||||
date = event["kwargs"].get("date", None)
|
||||
if date is None:
|
||||
date = str(datetime.date.today() - datetime.timedelta(days=1))
|
||||
|
||||
env = event["kwargs"]["env"]
|
||||
if os.environ.get("ENV", None) is None:
|
||||
load_env_vars(env)
|
||||
else:
|
||||
env = os.environ.get("ENV")
|
||||
|
||||
connection, cursor = get_connection_cursor(env)
|
||||
|
||||
@@ -355,6 +309,7 @@ def purge_old_data(event, context):
|
||||
success[table] = False
|
||||
|
||||
print("Elapsed: " + str(time.time() - start))
|
||||
success["elapsed"] = time.time() - start
|
||||
return success
|
||||
|
||||
|
||||
@@ -449,17 +404,28 @@ def get_query(date):
|
||||
"""
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
date = "2018-04-18"
|
||||
env = "prod"
|
||||
event = {
|
||||
"kwargs": {
|
||||
"date": date,
|
||||
"env": env,
|
||||
}
|
||||
@celery.task
|
||||
def etl():
|
||||
"""Perform the stats download."""
|
||||
results = {
|
||||
"downloads": get_daily_download_stats(),
|
||||
"__all__": update_all_package_stats(),
|
||||
"recent": update_recent_stats(),
|
||||
"purge": purge_old_data(),
|
||||
}
|
||||
context = None
|
||||
return results
|
||||
|
||||
|
||||
@celery.task
|
||||
def test():
|
||||
"""Test task for celery/beat."""
|
||||
print("hello test.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
date = "2018-04-19"
|
||||
env = "prod"
|
||||
print(date, env)
|
||||
print(get_daily_download_stats(event, context))
|
||||
print(update_all_package_stats(event, context))
|
||||
print(update_recent_stats(event, context))
|
||||
print(get_daily_download_stats(env, date))
|
||||
print(update_all_package_stats(env, date))
|
||||
print(update_recent_stats(env, date))
|
||||
|
||||
@@ -25,10 +25,6 @@
|
||||
Host:
|
||||
<a href="{{url_for('general.package', package='awscli')}}">AWS</a>
|
||||
</li>
|
||||
<li>
|
||||
Deployment:
|
||||
<a href="{{url_for('general.package', package='zappa')}}">Zappa</a>
|
||||
</li>
|
||||
<li>Authentication:
|
||||
<a href="{{url_for('general.package', package='github-flask')}}">GitHub OAuth</a>
|
||||
</li>
|
||||
@@ -65,4 +61,4 @@
|
||||
<a href="https://flynn.gg">Christopher Flynn</a>.
|
||||
</p>
|
||||
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
|
||||
@@ -12,8 +12,7 @@
|
||||
gtag('config', 'UA-101875606-5');
|
||||
</script>
|
||||
<!-- <script type="text/javascript"> // var host = "example.com"; // if ((host == window.location.host) && (window.location.protocol != "https:")) // window.location.protocol = "https"; </script> -->
|
||||
<!-- <link rel="stylesheet" href="/static/style.css"> -->
|
||||
<style>a small,a:hover small{color:#777}dt,th{color:#444}dl,hr,ol,p,pre,table,ul{margin:0 0 20px}.btn,.btn:hover,a{text-decoration:none}body{background-color:#fff;padding:.4in;font:16px/1.5 "Noto Sans","Helvetica Neue",Helvetica,Arial,sans-serif;color:#727272;font-weight:400;overflow:auto}footer,header{float:left;position:fixed;-webkit-font-smoothing:subpixel-antialiased}dt,strong{font-weight:700}h1,h2,h3,h4,h5,h6{color:#222;margin:0 0 20px}h1,h2,h3{line-height:1.1}h1{font-size:28px}h2{color:#393939}h3,h4,h5,h6{color:#494949}a{color:#39c}a:hover{color:#069}a small{font-size:11px;margin-top:-.3em;display:block}blockquote{border-left:1px solid #e5e5e5;margin:0;padding:0 0 0 20px;font-style:italic}code,pre{font-family:Monaco,Bitstream Vera Sans Mono,Lucida Console,Terminal,Consolas,Liberation Mono,DejaVu Sans Mono,Courier New,monospace;color:#333;font-size:12px}pre{padding:5px;background:#f8f8f8;border-radius:5px;border:1px solid #e5e5e5;overflow-x:auto}table{border-collapse:collapse}td,th{text-align:left;padding:2px 10px;border-bottom:1px solid #e5e5e5}img{max-width:100%}header{width:200px}header ul{list-style:none;height:40px;padding:0;background:#f4f4f4;border-radius:5px;border:1px solid #e0e0e0;width:270px}header li{width:89px;float:left;border-right:1px solid #e0e0e0;height:40px}header li:first-child a{border-radius:5px 0 0 5px}header li:last-child a{border-radius:0 5px 5px 0}header ul a{line-height:1;font-size:11px;color:#999;display:block;text-align:center;padding-top:6px;height:34px}header ul a:hover{color:#999}header ul a:active{background-color:#f0f0f0}strong{color:#222}header ul li+li+li{border-right:none;width:89px}header ul a strong{font-size:14px;display:block;color:#222}section{padding-left:225px;padding-bottom:20px}small{font-size:11px}hr{border:0;background:#e5e5e5;height:1px}footer{width:200px;bottom:20px}.btn{background:#f5c56c;background-image:-webkit-linear-gradient(top,#f5c56c,#b8842b);background-image:-moz-linear-gradient(top,#f5c56c,#b8842b);background-image:-ms-linear-gradient(top,#f5c56c,#b8842b);background-image:-o-linear-gradient(top,#f5c56c,#b8842b);background-image:linear-gradient(to bottom,#f5c56c,#b8842b);-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;text-shadow:1px 1px 3px #666;font-family:Arial;color:#fff;font-size:14px;padding:5px 10px}.btn:hover{background:#e08c43;background-image:-webkit-linear-gradient(top,#e08c43,#de9347);background-image:-moz-linear-gradient(top,#e08c43,#de9347);background-image:-ms-linear-gradient(top,#e08c43,#de9347);background-image:-o-linear-gradient(top,#e08c43,#de9347);background-image:linear-gradient(to bottom,#e08c43,#de9347)}@media print,screen and (max-width:960px){body{padding:0}div.wrapper{width:auto;margin:0}footer,header,section{float:none;position:static;width:auto}header{padding-right:320px}section{border:1px solid #e5e5e5;border-width:1px 0;padding:20px 0;margin:0 0 20px}header a small{display:inline}header ul{position:absolute;right:50px;top:52px}}@media print,screen and (max-width:720px){body{word-wrap:break-word}header{padding:0}header p.view,header ul{position:static}code,pre{word-wrap:normal}}@media print,screen and (max-width:480px){body{padding:0}header ul{width:99%}header li,header ul li+li+li{width:33%}}@media print{body{font-size:12pt;color:#444}}</style>
|
||||
<link rel="stylesheet" href="/static/style.css">
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="chrome=1">
|
||||
<title>
|
||||
|
||||
@@ -21,7 +21,6 @@ from pypistats.models.download import PythonMinorDownloadCount
|
||||
from pypistats.models.download import RECENT_CATEGORIES
|
||||
from pypistats.models.download import RecentDownloadCount
|
||||
from pypistats.models.download import SystemDownloadCount
|
||||
from sqlalchemy import distinct
|
||||
|
||||
blueprint = Blueprint("general", __name__, template_folder="templates")
|
||||
|
||||
@@ -49,7 +48,6 @@ def index():
|
||||
return redirect(f"/search/{package}")
|
||||
package_count = \
|
||||
RecentDownloadCount.query.filter_by(category="month").count()
|
||||
print(package_count)
|
||||
return render_template(
|
||||
"index.html",
|
||||
form=form,
|
||||
@@ -104,7 +102,6 @@ def package(package):
|
||||
if metadata["info"].get("requires_dist", None):
|
||||
metadata["requires"] = []
|
||||
for required in metadata["info"]["requires_dist"]:
|
||||
print(package, re.split(r"[^0-9a-zA-Z_.-]+", required))
|
||||
metadata["requires"].append(
|
||||
re.split(r"[^0-9a-zA-Z_.-]+", required)[0]
|
||||
)
|
||||
|
||||
44
requirements.txt
Normal file
44
requirements.txt
Normal file
@@ -0,0 +1,44 @@
|
||||
alembic==0.9.9 --hash=sha256:85bd3ea7633024e4930900bc64fb58f9742dedbc6ebb6ecf25be2ea9a3c1b32e
|
||||
amqp==2.2.2 --hash=sha256:4e28d3ea61a64ae61830000c909662cb053642efddbe96503db0e7783a6ee85b --hash=sha256:cba1ace9d4ff6049b190d8b7991f9c1006b443a5238021aca96dd6ad2ac9da22
|
||||
billiard==3.5.0.3 --hash=sha256:abd9ce008c9a71ccde2c816f8daa36246e92a21e6a799831b887d88277187ecd --hash=sha256:1d7b22bdc47aa52841120fcd22a74ae4fc8c13e9d3935643098184f5788c3ce6
|
||||
cachetools==2.0.1 --hash=sha256:4319bbb78172e7bcf99423e1ecd6914b32336ccfe97d2058ffe62e641a7f3abe --hash=sha256:ede01f2d3cbd6ddc9e35e16c2b0ce011d8bb70ce0dbaf282f5b4df24b213bc5d
|
||||
celery==4.1.0 --hash=sha256:81a67f0d53a688ec2bc8557bd5d6d7218f925a6f2e6df80e01560de9e28997ec --hash=sha256:77ff3730198d6a17b3c1f05579ebe570b579efb35f6d7e13dba3b1368d068b35
|
||||
certifi==2018.4.16 --hash=sha256:9fa520c1bacfb634fa7af20a76bcbd3d5fb390481724c597da32c719a7dca4b0 --hash=sha256:13e698f54293db9f89122b0581843a782ad0934a4fe0172d2a980ba77fc61bb7
|
||||
chardet==3.0.4 --hash=sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691 --hash=sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae
|
||||
click==6.7 --hash=sha256:29f99fc6125fbc931b758dc053b3114e55c77a6e4c6c3a2674a2dc986016381d --hash=sha256:f15516df478d5a56180fbf80e68f206010e6d160fc39fa508b65e035fd75130b
|
||||
flask==0.12.2 --hash=sha256:0749df235e3ff61ac108f69ac178c9770caeaccad2509cb762ce1f65570a8856 --hash=sha256:49f44461237b69ecd901cc7ce66feea0319b9158743dd27a2899962ab214dac1
|
||||
flask-login==0.4.1 --hash=sha256:c815c1ac7b3e35e2081685e389a665f2c74d7e077cb93cecabaea352da4752ec
|
||||
flask-migrate==2.1.1 --hash=sha256:493f9b3795985b9b4915bf3b7d16946697f027b73545384e7d9e3a79f989d2fe --hash=sha256:b709ca8642559c3c5a81a33ab10839fa052177accd5ba821047a99db635255ed
|
||||
flask-sqlalchemy==2.3.2 --hash=sha256:3bc0fac969dd8c0ace01b32060f0c729565293302f0c4269beed154b46bec50b --hash=sha256:5971b9852b5888655f11db634e87725a9031e170f37c0ce7851cf83497f56e53
|
||||
flask-wtf==0.14.2 --hash=sha256:d9a9e366b32dcbb98ef17228e76be15702cd2600675668bca23f63a7947fd5ac --hash=sha256:5d14d55cfd35f613d99ee7cba0fc3fbbe63ba02f544d349158c14ca15561cc36
|
||||
github-flask==3.2.0 --hash=sha256:24600b720f698bac10667b76b136995ba7821d884e58b27e2a18ca0e4760c786
|
||||
google-api-core==1.1.1 --hash=sha256:4885e5298e45aa587185c32bee54f95e79a05a926d69fcfd398c66b12b98b9a7 --hash=sha256:d23d5ae89e44ca1ddddec94e5f7c03f52402d192e66345d448b77ad5276b0fbe
|
||||
google-auth==1.4.1 --hash=sha256:34088434cb2a2409360b8f3cbc04195a465df1fb2aafad71ebbded77cbf08803 --hash=sha256:9051802d3dae256036cca9e34633a32c0ed1427730d4ebc513dff91ec8b6dd45
|
||||
google-cloud-bigquery==1.1.0 --hash=sha256:44d152e1de60cce8fe9d4f5c60ca4cebc88daab02b4d889bb0ebfcc19d54d7ec --hash=sha256:aed2b1d4db1e21d891522d6d6bb14476e6ba58c681cbb68eeb42c168a4e3fda9
|
||||
google-cloud-core==0.28.1 --hash=sha256:0090df83dbc5cb2405fa90844366d13176d1c0b48181c1807ab15f53be403f73 --hash=sha256:89e8140a288acec20c5e56159461d3afa4073570c9758c05d4e6cb7f2f8cc440
|
||||
google-resumable-media==0.3.1 --hash=sha256:116de90b9cd483b17c53618ee6a5a20f33e741c648140c8cc9c2141e07616ff1 --hash=sha256:97de518f8166d442cc0b61fab308bcd319dbb970981e667ec8ded44f5ce49836
|
||||
googleapis-common-protos==1.5.3 --hash=sha256:c075eddaa2628ab519e01b7d75b76e66c40eaa50fc52758d8225f84708950ef2
|
||||
idna==2.6 --hash=sha256:8c7309c718f94b3a625cb648ace320157ad16ff131ae0af362c9f21b80ef6ec4 --hash=sha256:2c6a5de3089009e3da7c5dde64a141dbc8551d5b7f6cf4ed7c2568d0cc520a8f
|
||||
itsdangerous==0.24 --hash=sha256:cbb3fcf8d3e33df861709ecaf89d9e6629cff0a217bc2848f1b41cd30d360519
|
||||
jinja2==2.10 --hash=sha256:74c935a1b8bb9a3947c50a54766a969d4846290e1e788ea44c1392163723c3bd --hash=sha256:f84be1bb0040caca4cea721fcbbbbd61f9be9464ca236387158b0feea01914a4
|
||||
kombu==4.1.0 --hash=sha256:01f0da9fe222a2183345004243d1518c0fbe5875955f1b24842f2d9c65709ade --hash=sha256:4249d9dd9dbf1fcec471d1c2def20653c9310dd1a217272d77e4844f9d5273cb
|
||||
mako==1.0.7 --hash=sha256:4e02fde57bd4abb5ec400181e4c314f56ac3e49ba4fb8b0d50bba18cb27d25ae
|
||||
markupsafe==1.0 --hash=sha256:a6be69091dac236ea9c6bc7d012beab42010fa914c459791d627dad4910eb665
|
||||
numpy==1.14.2 --hash=sha256:719d914f564f35cce4dc103808f8297c807c9f0297ac183ed81ae8b5650e698e --hash=sha256:0f6a5ed0cd7ab1da11f5c07a8ecada73fc55a70ef7bb6311a4109891341d7277 --hash=sha256:d0928076d9bd8a98de44e79b1abe50c1456e7abbb40af7ef58092086f1a6c729 --hash=sha256:d858423f5ed444d494b15c4cc90a206e1b8c31354c781ac7584da0d21c09c1c3 --hash=sha256:20cac3123d791e4bf8482a580d98d6b5969ba348b9d5364df791ba3a666b660d --hash=sha256:528ce59ded2008f9e8543e0146acb3a98a9890da00adf8904b1e18c82099418b --hash=sha256:56e392b7c738bd70e6f46cf48c8194d3d1dd4c5a59fae4b30c58bb6ef86e5233 --hash=sha256:99051e03b445117b26028623f1a487112ddf61a09a27e2d25e6bc07d37d94f25 --hash=sha256:768e777cc1ffdbf97c507f65975c8686ebafe0f3dc8925d02ac117acc4669ce9 --hash=sha256:675e0f23967ce71067d12b6944add505d5f0a251f819cfb44bdf8ee7072c090d --hash=sha256:a958bf9d4834c72dee4f91a0476e7837b8a2966dc6fcfc42c421405f98d0da51 --hash=sha256:bb370120de6d26004358611441e07acda26840e41dfedc259d7f8cc613f96495 --hash=sha256:f2b1378b63bdb581d5d7af2ec0373c8d40d651941d283a2afd7fc71184b3f570 --hash=sha256:a1413d06abfa942ca0553bf3bccaff5fdb36d55b84f2248e36228db871147dab --hash=sha256:7f76d406c6b998d6410198dcb82688dcdaec7d846aa87e263ccf52efdcfeba30 --hash=sha256:a7157c9ac6bddd2908c35ef099e4b643bc0e0ebb4d653deb54891d29258dd329 --hash=sha256:0fd65cbbfdbf76bbf80c445d923b3accefea0fe2c2082049e0ce947c81fe1d3f --hash=sha256:8c18ee4dddd5c6a811930c0a7c7947bf16387da3b394725f6063f1366311187d --hash=sha256:0739146eaf4985962f07c62f7133aca89f3a600faac891ce6c7f3a1e2afe5272 --hash=sha256:07e21f14490324cc1160db101e9b6c1233c33985af4cb1d301dd02650fea1d7f --hash=sha256:e6120d63b50e2248219f53302af7ec6fa2a42ed1f37e9cda2c76dbaca65036a7 --hash=sha256:6be6b0ca705321c178c9858e5ad5611af664bbdfae1df1541f938a840a103888 --hash=sha256:facc6f925c3099ac01a1f03758100772560a0b020fb9d70f210404be08006bcb
|
||||
pandas==0.22.0 --hash=sha256:68ac484e857dcbbd07ea7c6f516cc67f7f143f5313d9bc661470e7f473528882 --hash=sha256:12f2a19d0b0adf31170d98d0e8bcbc59add0965a9b0c65d39e0665400491c0c5 --hash=sha256:68b121d13177f5128a4c118bb4f73ba40df28292c038389961aa55ea5a996427 --hash=sha256:06efae5c00b9f4c6e6d3fe1eb52e590ff0ea8e5cb58032c724e04d31c540de53 --hash=sha256:02541a4fdd31315f213a5c8e18708abad719ee03eda05f603c4fe973e9b9d770 --hash=sha256:2907f3fe91ca2119ac3c38de6891bbbc83333bfe0d98309768fee28de563ee7a --hash=sha256:052a66f58783a59ea38fdfee25de083b107baa81fdbe38fabd169d0f9efce2bf --hash=sha256:244ae0b9e998cfa88452a49b20e29bf582cc7c0e69093876d505aec4f8e1c7fe --hash=sha256:66403162c8b45325a995493bdd78ad4d8be085e527d721dbfa773d56fbba9c88 --hash=sha256:af0dbac881f6f87acd325415adea0ce8cccf28f5d4ad7a54b6a1e176e2f7bf70 --hash=sha256:c2cd884794924687edbaad40d18ac984054d247bb877890932c4d41e3c3aba31 --hash=sha256:c372db80a5bcb143c9cb254d50f902772c3b093a4f965275197ec2d2184b1e61 --hash=sha256:97c8223d42d43d86ca359a57b4702ca0529c6553e83d736e93a5699951f0f8db --hash=sha256:587a9816cc663c958fcff7907c553b73fe196604f990bc98e1b71ebf07e45b44 --hash=sha256:44a94091dd71f05922eec661638ec1a35f26d573c119aa2fad964f10a2880e6c
|
||||
protobuf==3.5.2.post1 --hash=sha256:ac0067e3c60737865ed72bb7416e02297d229d960902802d874c0e167128c809 --hash=sha256:5c1c8f6a0a68a874e3beff89255959dd80fad45870e96c88944a1b81a22dd5f5 --hash=sha256:7c193e6964e752bd056735594826c5b03274ceb8f07349d3ae47d9766250ba96 --hash=sha256:bcfa99f5a82f5eaaf6e5cee5bfdca5a1670f5740aec1d93dae170645ed1a16b0 --hash=sha256:e269ab7a50bf0fa6fe6a88ea7dcc7a1079ae9450d9ab9b7730ac32916d55508b --hash=sha256:01ccd6d03449ae75b779fb5bf4ed62177d61afe3c5e6465ccf3f8b2e1a84afbe --hash=sha256:628a3bf0794a8b3cabb18db11eb67cc10e0cc6e5525d557ae7b682bb73fa2018 --hash=sha256:242e4c7ae565267a8bc8b92d707177f915607ea4bd73244bec6cbf4a49b96661 --hash=sha256:e7fd33a3474cbe18fd5b5620784a0fa21fcae3e402b1806e29c6b450c7f61706 --hash=sha256:cc94079ae6cbcea5ae194464a30f3223f075e06a0446f52bca9ddbeb6e9f412a --hash=sha256:7222d6616108b33ad6cbeff8117062a73c43cdc8fa8f64f6a322ebeb663e710e --hash=sha256:3f655e1f99c3e14d56ca900af1b9a4715b691319a295cc38939d7f77eabd5e7c --hash=sha256:76ef6ca3c50e4cfd044861586d5f1b352e0fe7f17f883df6c165bad5b4d0e10a --hash=sha256:560a38e692a69957a70ba0e5839aa67430efd63072bf91b0539dac19055694cd --hash=sha256:d5d9edfdc5a3a01d06062d677b121081629782edf0e05ca1be14f15bb947eeee --hash=sha256:869e12bcfb5759e683f53ec1dd6155b7be034065431da289f0cb4510040a0799 --hash=sha256:905414e5ea6cdb78d8730f66335755152b46685fcb9fc2f2134024e3ea9e8dcc --hash=sha256:adf716a89c9cc1891ead79a861c427071ef59172f0e11967b00565a9547b3bd0 --hash=sha256:1d92cc30b0b46cced33adde5853d920179eb5ea8eecdee9552502a7f29cc3f21 --hash=sha256:3b60685732bd0cbdc802dfcb6071efbcf5d927ce3127c13c33ea1a8efae3aa76
|
||||
psycopg2==2.7.4 --hash=sha256:aeaba399254ca79c299d9fe6aa811d3c3eac61458dee10270de7f4e71c624998 --hash=sha256:1d90379d01d0dc50ae9b40c863933d87ff82d51dd7d52cea5d1cb7019afd72cd --hash=sha256:36030ca7f4b4519ee4f52a74edc4ec73c75abfb6ea1d80ac7480953d1c0aa3c3 --hash=sha256:7cbc3b21ce2f681ca9ad2d8c0901090b23a30c955e980ebf1006d41f37068a95 --hash=sha256:b178e0923c93393e16646155794521e063ec17b7cc9f943f15b7d4b39776ea2c --hash=sha256:fe6a7f87356116f5ea840c65b032af17deef0e1a5c34013a2962dd6f99b860dd --hash=sha256:6f302c486132f8dd11f143e919e236ea4467d53bf18c451cac577e6988ecbd05 --hash=sha256:888bba7841116e529f407f15c6d28fe3ef0760df8c45257442ec2f14f161c871 --hash=sha256:932a4c101af007cb3132b1f8a9ffef23386acc53dad46536dc5ba43a3235ae02 --hash=sha256:179c52eb870110a8c1b460c86d4f696d58510ea025602cd3f81453746fccb94f --hash=sha256:33f9e1032095e1436fa9ec424abcbd4c170da934fb70e391c5d78275d0307c75 --hash=sha256:092a80da1b052a181b6e6c765849c9b32d46c5dac3b81bf8c9b83e697f3cdbe8 --hash=sha256:f3d3a88128f0c219bdc5b2d9ccd496517199660cea021c560a3252116df91cbd --hash=sha256:19983b77ec1fc2a210092aa0333ee48811fd9fb5f194c6cd5b927ed409aea5f8 --hash=sha256:027ae518d0e3b8fff41990e598bc7774c3d08a3a20e9ecc0b59fb2aaaf152f7f --hash=sha256:363fbbf4189722fc46779be1fad2597e2c40b3f577dc618f353a46391cf5d235 --hash=sha256:d74cf9234ba76426add5e123449be08993a9b13ff434c6efa3a07caa305a619f --hash=sha256:32702e3bd8bfe12b36226ba9846ed9e22336fc4bd710039d594b36bd432ae255 --hash=sha256:8eb94c0625c529215b53c08fb4e461546e2f3fc96a49c13d5474b5ad7aeab6cf --hash=sha256:8ebba5314c609a05c6955e5773c7e0e57b8dd817e4f751f30de729be58fa5e78 --hash=sha256:27467fd5af1dcc0a82d72927113b8f92da8f44b2efbdb8906bd76face95b596d --hash=sha256:b68e89bb086a9476fa85298caab43f92d0a6af135a5f433d1f6b6d82cafa7b55 --hash=sha256:0b9851e798bae024ed1a2a6377a8dab4b8a128a56ed406f572f9f06194e4b275 --hash=sha256:733166464598c239323142c071fa4c9b91c14359176e5ae7e202db6bcc1d2eb5 --hash=sha256:ad75fe10bea19ad2188c5cb5fc4cdf53ee808d9b44578c94a3cd1e9fc2beb656 --hash=sha256:8966829cb0d21a08a3c5ac971a2eb67c3927ae27c247300a8476554cc0ce2ae8 --hash=sha256:8bf51191d60f6987482ef0cfe8511bbf4877a5aa7f313d7b488b53189cf26209
|
||||
pyasn1==0.4.2 --hash=sha256:f81c96761fca60d64b1c9b79ec2e40cf9495a745cf570613079ef324aeb9672b --hash=sha256:7d626683e3d792cccc608da02498aff37ab4f3dafd8905d6bf755d11f9b26b43 --hash=sha256:e85895087905c65b5b594eb91f7522664c85545b147d5f4d4e7b1b07da8dcbdc --hash=sha256:5a0db897b311d265cde49615cf783f1c78613138605cdd0f907ecfa5b2aba3ee --hash=sha256:d5cd6ed995dba16fad0c521cfe31cd2d68400b53fcc2bce93326829be73ab6d1 --hash=sha256:a7efe807c4b83a859e2735c692b92ed7b567cfddc4163763412920041d876c2b --hash=sha256:b5a9ca48055b9a20f6d1b3d68e38692e5431c86a0f99ea602e61294e891fee5b --hash=sha256:c07d6e587b2f928366b1f67c09bda026a3e6fcc99e80a744dc67f8fca3895626 --hash=sha256:d84c2aea3cf43780e9e6a19f4e4dddee9f6976519020e64e47c57e5c7a8c3dd2 --hash=sha256:758cb50abddc03e4563fd9e7f03db56e3e87b58c0bd01247360326e5c0c7ffa5 --hash=sha256:0d7f6e959fe53f3960a23d73f35e1fce61348b30915b6664309ca756de7c1f89 --hash=sha256:d258b0a71994f7770599835249cece1caef3c70def868c4915e6e5ca49b67d15
|
||||
pyasn1-modules==0.2.1 --hash=sha256:b1f395cae2d669e0830cb023aa86f9f283b7a9aa32317d7f80d8e78aa2745812 --hash=sha256:854700bbdd01394e2ada9c1bfbd0ed9f5d0c551350dbbd023e88b11d2771ae06 --hash=sha256:598a6004ec26a8ab40a39ea955068cf2a3949ad9c0030da970f2e1ca4c9f1cc9 --hash=sha256:f53fe5bcebdf318f51399b250fe8325ef3a26d927f012cc0c8e0f9e9af7f9deb --hash=sha256:47fb6757ab78fe966e7c58b2030b546854f78416d653163f0ce9290cf2278e8b --hash=sha256:041e9fbafac548d095f5b6c3b328b80792f006196e15a232b731a83c93d59493 --hash=sha256:0cea139045c38f84abaa803bcb4b5e8775ea12a42af10019d942f227acc426c3 --hash=sha256:0cdca76a68dcb701fff58c397de0ef9922b472b1cb3ea9695ca19d03f1869787 --hash=sha256:72fd8b0c11191da088147c6e4678ec53e573923ecf60b57eeac9e97433e09fc2 --hash=sha256:c6747146e95d2b14cc2a8399b2b0bde3f93778f8f9ec704690d2b589c376c137 --hash=sha256:0f2e50d20bc670be170966638fa0ae603f0bc9ed6ebe8e97a6d1d4cef30cc889 --hash=sha256:af00ea8f2022b6287dc375b2c70f31ab5af83989fc6fe9eacd4976ce26cd7ccc
|
||||
python-dateutil==2.7.2 --hash=sha256:3220490fb9741e2342e1cf29a503394fdac874bc39568288717ee67047ff29df --hash=sha256:9d8074be4c993fbe4947878ce593052f71dac82932a677d49194d8ce9778002e
|
||||
python-editor==1.0.3 --hash=sha256:a3c066acee22a1c94f63938341d4fb374e3fdd69366ed6603d7b24bed1efc565
|
||||
pytz==2018.4 --hash=sha256:65ae0c8101309c45772196b21b74c46b2e5d11b6275c45d251b150d5da334555 --hash=sha256:c06425302f2cf668f1bba7a0a03f3c1d34d4ebeef2c72003da308b3947c7f749
|
||||
redis==2.10.6 --hash=sha256:8a1900a9f2a0a44ecf6e8b5eb3e967a9909dfed219ad66df094f27f7d6f330fb --hash=sha256:a22ca993cea2962dbb588f9f30d0015ac4afcc45bee27d3978c0dbe9e97c6c0f
|
||||
requests==2.18.4 --hash=sha256:6a1b267aa90cac58ac3a765d067950e7dbbf75b1da07e895d1f594193a40a38b --hash=sha256:9c443e7324ba5b85070c4a818ade28bfabedf16ea10206da1132edaa6dda237e
|
||||
rsa==3.4.2 --hash=sha256:43f682fea81c452c98d09fc316aae12de6d30c4b5c84226642cf8f8fd1c93abd --hash=sha256:25df4e10c263fb88b5ace923dd84bf9aa7f5019687b5e55382ffcdb8bede9db5
|
||||
six==1.11.0 --hash=sha256:832dc0e10feb1aa2c68dcc57dbb658f1c7e65b9b61af69048abc87a2db00a0eb --hash=sha256:70e8a77beed4562e7f14fe23a786b54f6296e34344c23bc42f07b15018ff98e9
|
||||
sqlalchemy==1.2.7 --hash=sha256:d6cda03b0187d6ed796ff70e87c9a7dce2c2c9650a7bc3c022cd331416853c31
|
||||
urllib3==1.22 --hash=sha256:06330f386d6e4b195fbfc736b297f58c5a892e4440e54d294d7004e3a9bbea1b --hash=sha256:cc44da8e1145637334317feebd728bd869a35285b93cbb4cca2577da7e62db4f
|
||||
vine==1.1.4 --hash=sha256:6849544be74ec3638e84d90bc1cf2e1e9224cc10d96cd4383ec3f69e9bce077b --hash=sha256:52116d59bc45392af9fdd3b75ed98ae48a93e822cee21e5fda249105c59a7a72
|
||||
werkzeug==0.14.1 --hash=sha256:d5da73735293558eb1651ee2fddc4d0dedcfa06538b8813a2e20011583c9e49b --hash=sha256:c3fd7a7d41976d9f44db327260e263132466836cef6f91512889ed60ad26557c
|
||||
wtforms==2.1 --hash=sha256:ffdf10bd1fa565b8233380cb77a304cd36fd55c73023e91d4b803c96bc11d46f
|
||||
2
run.sh
Normal file → Executable file
2
run.sh
Normal file → Executable file
@@ -1,3 +1,3 @@
|
||||
export FLASK_APP=pypistats/run.py
|
||||
export FLASK_DEBUG=1
|
||||
flask run
|
||||
flask run --host=0.0.0.0
|
||||
|
||||
@@ -1,119 +0,0 @@
|
||||
{
|
||||
"dev": {
|
||||
"app_function": "pypistats.run.app",
|
||||
"aws_region": "REDACTED",
|
||||
"certificate_arn": "REDACTED",
|
||||
"delete_local_zip": true,
|
||||
"domain": "dev.pypistats.org",
|
||||
"environment_variables": {
|
||||
"ENV": "dev"
|
||||
},
|
||||
"events": [
|
||||
{
|
||||
"function": "pypistats.tasks.pypi.get_daily_download_stats",
|
||||
"kwargs": {"env": "dev"},
|
||||
"expression": "cron(0 1 * * ? *)"
|
||||
},
|
||||
{
|
||||
"function": "pypistats.tasks.pypi.update_all_package_stats",
|
||||
"kwargs": {"env": "dev"},
|
||||
"expression": "cron(10 1 * * ? *)"
|
||||
},
|
||||
{
|
||||
"function": "pypistats.tasks.pypi.update_recent_stats",
|
||||
"kwargs": {"env": "dev"},
|
||||
"expression": "cron(15 1 * * ? *)"
|
||||
},
|
||||
{
|
||||
"function": "pypistats.tasks.pypi.purge_old_data",
|
||||
"kwargs": {"env": "dev"},
|
||||
"expression": "cron(20 1 * * ? *)"
|
||||
}
|
||||
],
|
||||
"exclude": [
|
||||
"docs/",
|
||||
"ignore/",
|
||||
"migrations/",
|
||||
"tests/",
|
||||
"pypistats/secret/",
|
||||
"pypistats/static/",
|
||||
"boto3*",
|
||||
"botocore*"
|
||||
],
|
||||
"keep_warm": false,
|
||||
"profile_name": "REDACTED",
|
||||
"project_name": "pypistats",
|
||||
"memory_size": 128,
|
||||
"remote_env": "REDACTED",
|
||||
"route53_enabled": true,
|
||||
"runtime": "python3.6",
|
||||
"s3_bucket": "pypistats",
|
||||
"slim_handler": false,
|
||||
"timeout_seconds": 30,
|
||||
"vpc_config" : {
|
||||
"SubnetIds": [
|
||||
"REDACTED",
|
||||
],
|
||||
"SecurityGroupIds": ["REDACTED"]
|
||||
}
|
||||
},
|
||||
"prod": {
|
||||
"app_function": "pypistats.run.app",
|
||||
"aws_region": "REDACTED",
|
||||
"certificate_arn": "REDACTED",
|
||||
"delete_local_zip": true,
|
||||
"domain": "pypistats.org",
|
||||
"environment_variables": {
|
||||
"ENV": "prod"
|
||||
},
|
||||
"events": [
|
||||
{
|
||||
"function": "pypistats.tasks.pypi.get_daily_download_stats",
|
||||
"kwargs": {"env": "prod"},
|
||||
"expression": "cron(0 1 * * ? *)"
|
||||
},
|
||||
{
|
||||
"function": "pypistats.tasks.pypi.update_all_package_stats",
|
||||
"kwargs": {"env": "prod"},
|
||||
"expression": "cron(10 1 * * ? *)"
|
||||
},
|
||||
{
|
||||
"function": "pypistats.tasks.pypi.update_recent_stats",
|
||||
"kwargs": {"env": "prod"},
|
||||
"expression": "cron(15 1 * * ? *)"
|
||||
},
|
||||
{
|
||||
"function": "pypistats.tasks.pypi.purge_old_data",
|
||||
"kwargs": {"env": "prod"},
|
||||
"expression": "cron(20 1 * * ? *)"
|
||||
}
|
||||
],
|
||||
"exclude": [
|
||||
"docs/",
|
||||
"ignore/",
|
||||
"migrations/",
|
||||
"tests/",
|
||||
"pypistats/secret/",
|
||||
"pypistats/static/",
|
||||
"boto3*",
|
||||
"botocore*"
|
||||
],
|
||||
"keep_warm": true,
|
||||
"keep_warm_expression": "rate(4 minutes)",
|
||||
"profile_name": "REDACTED",
|
||||
"project_name": "pypistats",
|
||||
"memory_size": 128,
|
||||
"remote_env": "REDACTED",
|
||||
"route53_enabled": true,
|
||||
"runtime": "python3.6",
|
||||
"s3_bucket": "REDACTED",
|
||||
"slim_handler": false,
|
||||
"timeout_seconds": 30,
|
||||
"vpc_config" : {
|
||||
"SubnetIds": [
|
||||
"REDACTED",
|
||||
],
|
||||
"SecurityGroupIds": ["REDACTED"]
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user