diff --git a/.env.prod b/.env.prod deleted file mode 100644 index 7e114b2..0000000 --- a/.env.prod +++ /dev/null @@ -1,2 +0,0 @@ -PERSONAL_API_USERNAME=zev -PERSONAL_API_PASS=14Years?zz diff --git a/.gitignore b/.gitignore index c65744b..7e3332f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ -Pipfile +Pipfile.lock codealike.json data/certbot/ +personal_api.egg-info/ diff --git a/Dockerfile b/Dockerfile index a8df4a6..f8164d9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ FROM python:3.8 -COPY requirements.txt /tmp -RUN pip install -r /tmp/requirements.txt -COPY . /tmp/personal_api -RUN pip install -e /tmp/personal_api +COPY . /usr/src/app +RUN cd /usr/src/app && pip install -r requirements.txt ENV PERSONAL_API_SQLALCHEMY_DATABASE_URL postgresql://doadmin:q606mxj40xfltziw@zev-api-db-do-user-246213-0.db.ondigitalocean.com:25060/defaultdb -CMD gunicorn -w 4 -k uvicorn.workers.UvicornWorker personal_api.main:app -b 0.0.0.0 +ENV PERSONAL_API_USERNAME zev +ENV PERSONAL_API_PASS 14Yearszz +CMD gunicorn -w 4 -k uvicorn.workers.UvicornWorker personal_api.main:app -b 0.0.0.0:80 --preload --access-logfile /var/log/access.log --log-level info --error-logfile /var/log/error.log diff --git a/_docker-compose.yml b/_docker-compose.yml new file mode 100644 index 0000000..f45898b --- /dev/null +++ b/_docker-compose.yml @@ -0,0 +1,7 @@ +version: '3.7' + +services: + app: + build: . + ports: + - '5001:80' diff --git a/config.py b/config.py index acba345..f7e4dd7 100644 --- a/config.py +++ b/config.py @@ -1,7 +1,7 @@ import os PERSONAL_API_USERNAME = os.getenv("PERSONAL_API_USERNAME") -PERSONAL_API_PASS = os.getenv("PERSONAL_API_USERNAME") +PERSONAL_API_PASS = os.getenv("PERSONAL_API_PASS") # must be a postgres instance SQLALCHEMY_DATABASE_URL = os.getenv("PERSONAL_API_SQLALCHEMY_DATABASE_URL") \ No newline at end of file diff --git a/data/nginx/app.conf b/data/nginx/app.conf new file mode 100644 index 0000000..62c4bbf --- /dev/null +++ b/data/nginx/app.conf @@ -0,0 +1,31 @@ +server { + listen 80; + server_name api.averba.ch; location / { + return 301 https://$host$request_uri; + } + + location /.well-known/acme-challenge/ { + root /var/www/certbot; + } + +} + +server { + listen 443 ssl; + server_name api.averba.ch; + + ssl_certificate /etc/letsencrypt/live/api.averba.ch/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/api.averba.ch/privkey.pem; + include /etc/letsencrypt/options-ssl-nginx.conf; + ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; + + + location / { + proxy_pass http://personal-api:8000/; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_connect_timeout 300s; + proxy_read_timeout 300s; + + } +} diff --git a/docker-compose.yml b/docker-compose.yml index a172743..628df8f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,16 +1,20 @@ version: '3.7' services: + app: + build: . + ports: + - '5001:80' nginx: container_name: nginx image: nginx:latest depends_on: - app ports: - - "80:8000" + - '80:80' networks: - my-network volumes: - - ./data/nginx:/etc/nginx/conf.d + - ./data/nginx/app.conf:/etc/nginx/conf.d/default.conf - ./data/certbot/conf:/etc/letsencrypt - ./data/certbot/www:/var/www/certbot command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'" @@ -20,21 +24,5 @@ services: - ./data/certbot/conf:/etc/letsencrypt - ./data/certbot/www:/var/www/certbot entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'" - app: - build: - context: ./ - image: personal_api:0.0.1 - container_name: personal_api - env_file: - - ./.env.prod - volumes: - - ./:/personal_api/ - command: gunicorn -w 4 -k uvicorn.workers.UvicornWorker personal_api.main:app -b 0.0.0.0:8000 - expose: - - "8000" - networks: - my-network: - aliases: - - personal-api networks: my-network: diff --git a/personal_api/main.py b/personal_api/main.py index 9364849..f2c7d58 100644 --- a/personal_api/main.py +++ b/personal_api/main.py @@ -2,6 +2,7 @@ from typing import List from fastapi import FastAPI, Depends, HTTPException from fastapi.security import HTTPBasic, HTTPBasicCredentials +import rollbar from sqlalchemy.orm import Session from starlette.requests import Request from starlette.status import HTTP_401_UNAUTHORIZED @@ -17,6 +18,7 @@ from .database import SessionLocal, Base, engine Base.metadata.create_all(bind=engine) app = FastAPI() security = HTTPBasic() +rollbar.init('42da7f4812c043f9b19dcf8d2089d162') def get_db(): @@ -29,6 +31,8 @@ def get_db(): def get_current_username(credentials: HTTPBasicCredentials = Depends(security)): + rollbar.report_message(f"username and pass: {PERSONAL_API_USERNAME}, {PERSONAL_API_PASS}", 'info') + if credentials.username != PERSONAL_API_USERNAME or credentials.password != PERSONAL_API_PASS: raise HTTPException( status_code=HTTP_401_UNAUTHORIZED, @@ -151,3 +155,4 @@ def delete_project(post_id: int, delete(db, models.Post, post_id) except DoesntExist: raise HTTPException(status_code=404) + diff --git a/pyproject.toml b/pyproject.toml deleted file mode 100644 index f4f6e90..0000000 --- a/pyproject.toml +++ /dev/null @@ -1,37 +0,0 @@ -[tool.poetry] -name = "personal_api" -version = "0.1.0" -description = "" -authors = ["zevav "] - -[tool.poetry.dependencies] -python = "^3.8" -click = "=7.0" -websockets = "=8.0.2" -regex = "=2019.8.19" -psycopg2 = "=2.8.4" -six = "=1.12.0" -certifi = "=2019.9.11" -pydantic = "=0.32.2" -sqlalchemy = "=1.3.10" -uvloop = "=0.14.0rc1" -urllib3 = "=1.25.6" -httptools = "=0.0.13" -pytz = "=2019.3" -tzlocal = "=2.0.0" -python-dateutil = "=2.8.0" -dateparser = "=0.7.2" -h11 = "=0.8.1" -uvicorn = "=0.9.1" -chardet = "=3.0.4" -fastapi = "=0.42.0" -requests = "=2.22.0" -idna = "=2.8" -starlette = "=0.12.9" -gunicorn = "^19.9" - -[tool.poetry.dev-dependencies] - -[build-system] -requires = ["poetry>=0.12"] -build-backend = "poetry.masonry.api" diff --git a/requirements.txt b/requirements.txt index a68e23b..4fdb110 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,103 +1,28 @@ -certifi==2019.9.11 \ - --hash=sha256:e4f3620cfea4f83eedc95b24abd9cd56f3c4b146dd0177e83a21b4eb49e21e50 \ - --hash=sha256:fd7c7c74727ddcf00e9acd26bba8da604ffec95bf1c2144e67aff7a8b50e6cef -chardet==3.0.4 \ - --hash=sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae \ - --hash=sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691 -click==7.0 \ - --hash=sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13 \ - --hash=sha256:5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7 -dateparser==0.7.2 \ - --hash=sha256:983d84b5e3861cb0aa240cad07f12899bb10b62328aae188b9007e04ce37d665 \ - --hash=sha256:e1eac8ef28de69a554d5fcdb60b172d526d61924b1a40afbbb08df459a36006b -fastapi==0.42.0 \ - --hash=sha256:38356cf424392142a561f32ab49113dec6e2ab7318862ae14d5e1d7ede16d14f \ - --hash=sha256:48cb522c1c993e238bfe272fbb18049cbd4bf5b9d6c0d4a4fa113cc790e8196c -gunicorn==19.9.0 \ - --hash=sha256:aa8e0b40b4157b36a5df5e599f45c9c76d6af43845ba3b3b0efe2c70473c2471 \ - --hash=sha256:fa2662097c66f920f53f70621c6c58ca4a3c4d3434205e608e121b5b3b71f4f3 -h11==0.8.1 \ - --hash=sha256:acca6a44cb52a32ab442b1779adf0875c443c689e9e028f8d831a3769f9c5208 \ - --hash=sha256:f2b1ca39bfed357d1f19ac732913d5f9faa54a5062eca7d2ec3a916cfb7ae4c7 -httptools==0.0.13 \ - --hash=sha256:e00cbd7ba01ff748e494248183abc6e153f49181169d8a3d41bb49132ca01dfc -idna==2.8 \ - --hash=sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407 \ - --hash=sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c -psycopg2==2.8.4 \ - --hash=sha256:47fc642bf6f427805daf52d6e52619fe0637648fe27017062d898f3bf891419d \ - --hash=sha256:72772181d9bad1fa349792a1e7384dde56742c14af2b9986013eb94a240f005b \ - --hash=sha256:8396be6e5ff844282d4d49b81631772f80dabae5658d432202faf101f5283b7c \ - --hash=sha256:893c11064b347b24ecdd277a094413e1954f8a4e8cdaf7ffbe7ca3db87c103f0 \ - --hash=sha256:965c4c93e33e6984d8031f74e51227bd755376a9df6993774fd5b6fb3288b1f4 \ - --hash=sha256:9ab75e0b2820880ae24b7136c4d230383e07db014456a476d096591172569c38 \ - --hash=sha256:b0845e3bdd4aa18dc2f9b6fb78fbd3d9d371ad167fd6d1b7ad01c0a6cdad4fc6 \ - --hash=sha256:dca2d7203f0dfce8ea4b3efd668f8ea65cd2b35112638e488a4c12594015f67b \ - --hash=sha256:ed686e5926929887e2c7ae0a700e32c6129abb798b4ad2b846e933de21508151 \ - --hash=sha256:ef6df7e14698e79c59c7ee7cf94cd62e5b869db369ed4b1b8f7b729ea825712a \ - --hash=sha256:f898e5cc0a662a9e12bde6f931263a1bbd350cfb18e1d5336a12927851825bb6 -pydantic==0.32.2 \ - --hash=sha256:18598557f0d9ab46173045910ed50458c4fb4d16153c23346b504d7a5b679f77 \ - --hash=sha256:6a9335c968e13295430a208487e74d69fef40168b72dea8d975765d14e2da660 \ - --hash=sha256:6f5eb88fe4c21380aa064b7d249763fc6306f0b001d7e7d52d80866d1afc9ed3 \ - --hash=sha256:bc6c6a78647d7a65a493e1107572d993f26a652c49183201e3c7d23924bf7311 \ - --hash=sha256:e1a63b4e6bf8820833cb6fa239ffbe8eec57ccdd7d66359eff20e68a83c1deeb \ - --hash=sha256:ede2d65ae33788d4e26e12b330b4a32c53cb14131c65bca3a59f037c73f6ee7a -python-dateutil==2.8.0 \ - --hash=sha256:7e6584c74aeed623791615e26efd690f29817a27c73085b78e4bad02493df2fb \ - --hash=sha256:c89805f6f4d64db21ed966fda138f8a5ed7a4fdbc1a8ee329ce1b74e3c74da9e -pytz==2019.3 \ - --hash=sha256:1c557d7d0e871de1f5ccd5833f60fb2550652da6be2693c1e02300743d21500d \ - --hash=sha256:b02c06db6cf09c12dd25137e563b31700d3b80fcc4ad23abb7a315f2789819be -regex==2019.08.19 \ - --hash=sha256:1e9f9bc44ca195baf0040b1938e6801d2f3409661c15fe57f8164c678cfc663f \ - --hash=sha256:587b62d48ca359d2d4f02d486f1f0aa9a20fbaf23a9d4198c4bed72ab2f6c849 \ - --hash=sha256:835ccdcdc612821edf132c20aef3eaaecfb884c9454fdc480d5887562594ac61 \ - --hash=sha256:93f6c9da57e704e128d90736430c5c59dd733327882b371b0cae8833106c2a21 \ - --hash=sha256:a46f27d267665016acb3ec8c6046ec5eae8cf80befe85ba47f43c6f5ec636dcd \ - --hash=sha256:c5c8999b3a341b21ac2c6ec704cfcccbc50f1fedd61b6a8ee915ca7fd4b0a557 \ - --hash=sha256:d4d1829cf97632673aa49f378b0a2c3925acd795148c5ace8ef854217abbee89 \ - --hash=sha256:d96479257e8e4d1d7800adb26bf9c5ca5bab1648a1eddcac84d107b73dc68327 \ - --hash=sha256:f20f4912daf443220436759858f96fefbfc6c6ba9e67835fd6e4e9b73582791a \ - --hash=sha256:f2b37b5b2c2a9d56d9e88efef200ec09c36c7f323f9d58d0b985a90923df386d \ - --hash=sha256:fe765b809a1f7ce642c2edeee351e7ebd84391640031ba4b60af8d91a9045890 -requests==2.22.0 \ - --hash=sha256:11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4 \ - --hash=sha256:9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31 -six==1.12.0 \ - --hash=sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c \ - --hash=sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73 -sqlalchemy==1.3.10 \ - --hash=sha256:0f0768b5db594517e1f5e1572c73d14cf295140756431270d89496dc13d5e46c -starlette==0.12.9 \ - --hash=sha256:c2ac9a42e0e0328ad20fe444115ac5e3760c1ee2ac1ff8cdb5ec915c4a453411 -tzlocal==2.0.0 \ - --hash=sha256:11c9f16e0a633b4b60e1eede97d8a46340d042e67b670b290ca526576e039048 \ - --hash=sha256:949b9dd5ba4be17190a80c0268167d7e6c92c62b30026cf9764caf3e308e5590 -urllib3==1.25.6 \ - --hash=sha256:3de946ffbed6e6746608990594d08faac602528ac7015ac28d33cee6a45b7398 \ - --hash=sha256:9a107b99a5393caf59c7aa3c1249c16e6879447533d0887f4336dde834c7be86 -uvicorn==0.9.1 \ - --hash=sha256:33c7cfcf71450d2170c9a4c4c7559767329040a36b159e3889554132e4b89457 -uvloop==0.14.0rc1 \ - --hash=sha256:182617c2992a79b268bfd193691c4aacb93634e9d8d96edf560a842a6206411d \ - --hash=sha256:2a0268553d2920108b05250c9711060313851daa60b1052c38b6520320aa50b1 \ - --hash=sha256:32d2fe6ee6be28a99661e1f02bf6cedb99711df1065a3fb7ba7dd73ccb85f768 \ - --hash=sha256:448b13a1adfc47745b880b5d5b34c975c7851b1cd3b0eafe2569b2250190c797 \ - --hash=sha256:469e0e3b80f245ed32f054174e6a69e6a01715dbbb24eb917733fe5af09ad306 \ - --hash=sha256:682fa2ab24a758831f531dca122f128373c3dd95a3c8885b5fd1c48775d0024f \ - --hash=sha256:9967fd537f3164607d153900aaae036e9a18015d8478f84406ba58b183f5abfc \ - --hash=sha256:9ab030794432c47b78199d3f268ac2c898ae85fb9f09e10ae03dd7af62904b0e \ - --hash=sha256:c1d55b6926d956a29cf5d7cc891004602ea7cd006b0b80354b9b3d973ca9027f -websockets==8.0.2 \ - --hash=sha256:049e694abe33f8a1d99969fee7bfc0ae6761f7fd5f297c58ea933b27dd6805f2 \ - --hash=sha256:73ce69217e4655783ec72ce11c151053fcbd5b837cc39de7999e19605182e28a \ - --hash=sha256:83e63aa73331b9ca21af61df8f115fb5fbcba3f281bee650a4ad16a40cd1ef15 \ - --hash=sha256:882a7266fa867a2ebb2c0baaa0f9159cabf131cf18c1b4270d79ad42f9208dc5 \ - --hash=sha256:8c77f7d182a6ea2a9d09c2612059f3ad859a90243e899617137ee3f6b7f2b584 \ - --hash=sha256:8d7a20a2f97f1e98c765651d9fb9437201a9ccc2c70e94b0270f1c5ef29667a3 \ - --hash=sha256:a7affaeffbc5d55681934c16bb6b8fc82bb75b175e7fd4dcca798c938bde8dda \ - --hash=sha256:c82e286555f839846ef4f0fdd6910769a577952e1e26aa8ee7a6f45f040e3c2b \ - --hash=sha256:e906128532a14b9d264a43eb48f9b3080d53a9bda819ab45bf56b8039dc606ac \ - --hash=sha256:e9102043a81cdc8b7c8032ff4bce39f6229e4ac39cb2010946c912eeb84e2cb6 \ - --hash=sha256:f5cb2683367e32da6a256b60929a3af9c29c212b5091cf5bace9358d03011bf5 +-i https://pypi.org/simple +-e . +certifi==2019.9.11 +chardet==3.0.4 +click==7.0 +dateparser==0.7.2 +dnspython==1.16.0 +email-validator==1.0.5 +fastapi==0.42.0 +gunicorn==20.0.0 +h11==0.8.1 +httptools==0.0.13 +idna==2.8 +psycopg2==2.8.4 +pydantic==0.32.2 +python-dateutil==2.8.0 +pytz==2019.3 +regex==2019.8.19 +requests==2.22.0 +rollbar==0.14.7 +six==1.12.0 +sqlalchemy==1.3.10 +starlette==0.12.9 +tzlocal==2.0.0 +urllib3==1.25.6 +uvicorn==0.9.1 +uvloop==0.14.0rc1 +websockets==8.0.2 diff --git a/setup.py b/setup.py index e1840d5..b0d855c 100644 --- a/setup.py +++ b/setup.py @@ -1,5 +1,13 @@ from setuptools import setup -setup(name='personal_api', - packages=["personal_api"], +setup( + name='personal-api', + version='0.1', + description='Your own web API for your data.', + url='http://github.com/zevaverbach/personal-api', + author='Zev Averbach', + author_email='zev@averba.ch', + license='MIT', + packages=['personal_api'], + zip_safe=False ) diff --git a/tests.py b/tests.py index 09130f9..4996fd7 100644 --- a/tests.py +++ b/tests.py @@ -8,7 +8,6 @@ from personal_api.main import app from personal_api.models import Resume, Availability, Project, Post client = TestClient(app) - VALID_AUTH = (PERSONAL_API_USERNAME, PERSONAL_API_PASS)