From a484c87b7a58c2590bd43ac40860011393dab71d Mon Sep 17 00:00:00 2001 From: Yahialabeeb Date: Thu, 30 Dec 2021 21:59:45 +0200 Subject: [PATCH] merge works --- .gitignore | 122 +++++++++++++++ Dockerfile | 16 ++ accounts/serializer.py | 17 +- accounts/urls.py | 6 +- accounts/views.py | 6 +- api_tester.py | 145 ++++++++++++++++++ db.sqlite3 | Bin 143360 -> 147456 bytes docker-compose.yml | 10 ++ heroku.yml | 7 + .../migrations/0003_alter_customuser_image.py | 18 +++ hospital/migrations/0004_customuser_group.py | 21 +++ .../__pycache__/0001_initial.cpython-39.pyc | Bin 1064 -> 1043 bytes .../0002_customuser_image.cpython-39.pyc | Bin 636 -> 615 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 187 -> 166 bytes hospital/models.py | 5 +- hospital/serializers.py | 6 +- hospital/urls.py | 6 +- hospital/views.py | 7 +- lifeshare/urls.py | 4 +- templates/base.html | 14 -- templates/registration/signup.html | 13 -- views.py | 3 + 22 files changed, 384 insertions(+), 42 deletions(-) create mode 100644 .gitignore create mode 100644 Dockerfile create mode 100644 api_tester.py create mode 100644 docker-compose.yml create mode 100644 heroku.yml create mode 100644 hospital/migrations/0003_alter_customuser_image.py create mode 100644 hospital/migrations/0004_customuser_group.py delete mode 100644 templates/base.html delete mode 100644 templates/registration/signup.html create mode 100644 views.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..182f34c --- /dev/null +++ b/.gitignore @@ -0,0 +1,122 @@ +Source: https://github.com/github/gitignore/blob/master/Python.gitignore + +# User generated +ENV/ +.vscode +.idea +.DS_Store +.history + + +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class +.pytest_cache/ + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +.static_storage/ +.media/ +local_settings.py + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ + +# js +node_modules/ +.next/ + +# poetry +poetry.lock \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..8f47e90 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,16 @@ +# Python version +FROM python:3 + +# Set environment variables +ENV PYTHONDONTWRITEBYTECODE 1 +ENV PYTHONUNBUFFERED 1 + +# Set work directory +WORKDIR /code + +# Install dependencies +COPY requirements.txt /code/ +RUN pip install -r requirements.txt + +# Copy project +COPY . /code/ \ No newline at end of file diff --git a/accounts/serializer.py b/accounts/serializer.py index 8873d1b..887c2fa 100644 --- a/accounts/serializer.py +++ b/accounts/serializer.py @@ -1,6 +1,8 @@ from django.db.models import fields from rest_framework import serializers from .models import Account +from rest_framework_simplejwt.serializers import TokenObtainPairSerializer + class AddSerializer(serializers.ModelSerializer): password = serializers.CharField(write_only=True) @@ -31,4 +33,17 @@ class Meta: 'email','password','age','blood_type','phone_number','location', 'chronic_diseases','data','donate','group','image' ) - \ No newline at end of file + +class MyTokenObtainPairSerializer(TokenObtainPairSerializer): + def validate(self, attrs): + data = super().validate(attrs) + refresh = self.get_token(self.user) + data['refresh'] = str(refresh) + data['access'] = str(refresh.access_token) + + # Add extra responses here + data['id'] = self.user.id + data['username'] = self.user.username + + return data + diff --git a/accounts/urls.py b/accounts/urls.py index bc638f2..77507ce 100644 --- a/accounts/urls.py +++ b/accounts/urls.py @@ -1,9 +1,9 @@ from django.urls import path -from .views import AddListView,DetailAddView,ListView +from .views import AddListView,DetailAddView,ListView,CustomObtainAuthToken urlpatterns = [ - path('',AddListView.as_view(),name= 'add_data'), + path('signup',AddListView.as_view(),name= 'add_data'), path('',DetailAddView.as_view(),name = 'detail_data'), - # path('',DetailAddView.as_view(),name = 'detail_dataint'), + path("auth/", CustomObtainAuthToken.as_view()), path('view',ListView.as_view(),name = 'list_data') ] \ No newline at end of file diff --git a/accounts/views.py b/accounts/views.py index 54a1845..a72aab0 100644 --- a/accounts/views.py +++ b/accounts/views.py @@ -1,12 +1,16 @@ from django.shortcuts import render from rest_framework import generics, permissions -from .serializer import AddSerializer +from .serializer import AddSerializer,MyTokenObtainPairSerializer from .models import Account from rest_framework import permissions from django.shortcuts import get_object_or_404 +from rest_framework_simplejwt.views import TokenObtainPairView from .models import User # Create your views here. +class CustomObtainAuthToken(TokenObtainPairView): + serializer_class = MyTokenObtainPairSerializer + class AddListView(generics.CreateAPIView): serializer_class = AddSerializer queryset = Account.objects.all() diff --git a/api_tester.py b/api_tester.py new file mode 100644 index 0000000..782e8c6 --- /dev/null +++ b/api_tester.py @@ -0,0 +1,145 @@ +import fire +import requests + +API_HOST = "https://django34.herokuapp.com/" +RESOURCE_URI = "cookie_stands" +USERNAME = "yahialabib" +PASSWORD = "123123" + + +class ApiTester: + """CLI for testing API""" + + def __init__(self, host=API_HOST): + self.host = host + + def fetch_tokens(self): + """Fetches access and refresh JWT tokens from api + Returns: + tuple: access,refresh + """ + + token_url = f"{self.host}/api/token/" + + response = requests.post( + token_url, json={"username": USERNAME, "password": PASSWORD} + ) + + data = response.json() + + tokens = data["access"], data["refresh"] + + return tokens + + def get_all(self): + """get list of all resources from api + Usage: python api_tester.py get_all + Returns: JSON + """ + access_token = self.fetch_tokens()[0] + + url = f"{self.host}/api/all/" + + headers = { + "Authorization": f"Bearer {access_token}", + } + + response = requests.get(url, headers=headers) + + return response.json() + + def get_one(self, id): + """get 1 resource by id from api + Usage: + python api_tester.py get_one 1 + Returns: JSON + """ + access_token = self.fetch_tokens()[0] + + url = f"{self.host}/api/{id}" + + headers = { + "Authorization": f"Bearer {access_token}", + } + + response = requests.get(url, headers=headers) + + return response.json() + + # TODO adjust parameter names to match API + def create(self, name, description=None, owner=None): + """creates a resource in api + Usage: + python api_tester.py create / + --name=required --description=optional --owner=optional + Returns: JSON + """ + + access_token = self.fetch_tokens()[0] + + url = f"{self.host}/api/all" + + headers = { + "Authorization": f"Bearer {access_token}", + } + + data = { + "name": name, + "description": description, + "owner": owner, + } + + response = requests.post(url, json=data, headers=headers) + + return response.json() + + def update(self, id, name=None, description=None, owner=None): + """updates a resource in api + Usage: + python api_tester.py update 1 / + --name=optional --description=optional --owner=optional + Returns: JSON + """ + + access_token = self.fetch_tokens()[0] + + url = f"{self.host}/api/{id}/" + + headers = { + "Authorization": f"Bearer {access_token}", + } + + original = self.get_cookiestand(id) + + data = { + "name": name or original["name"], + "description": description or original["description"], + "owner": owner or original["owner"], + } + + response = requests.put(url, json=data, headers=headers) + + return response.text + + def delete(self, id): + """deletes a resource in api + Usage: + python api_tester.py delete 1 + Returns: Empty string if no error + """ + + access_token = self.fetch_tokens()[0] + + url = f"{self.host}/api/{id}/" + + headers = { + "Authorization": f"Bearer {access_token}", + } + + response = requests.delete(url, headers=headers) + + return response.text + + +if __name__ == "__main__": + fire.Fire(ApiTester) \ No newline at end of file diff --git a/db.sqlite3 b/db.sqlite3 index 8f3da343fc0551d15a6d18843920a0e2a711628e..79e3f5355f3fe0ccc7aa76139acee6c78e3c488b 100644 GIT binary patch delta 1649 zcmai!OH3O_7{_<~sMj{@AuV8NWxN>EKwR)X{8pmI7(;>Z2r)G@0<*^J2N>J2y*6+$ zoAwk?8svjjMQR$Q>O(zLmQgMBaf%d0>4ig6sWehij!|2w>YO@Ihv?Rp{Msugt|JJd7rvvhxceFnt{0a+gyIhQPF~h*Ko#c{D)~M6PLZFH z=T3J>5slRuj;9ilG!rEV!sJ`#Qt9{_mtvE?P%_RXD1svUNvfYFaMJEDkq*i{K$>W? z-8|SXWV`CKX&)0!3yF0#B5O>DZCHaOr>(U0wEF25sOO}UHU~itm`wy}A?Y?DyXU_a z@;9~ZD!bz`L0avksl>l5Zv}XM+h}}2sg{aqQ21>SyadqvcSb`;he9|i6fPn#1Am3z z!UOmX`~WV(?IJ%6+tm_H7dSecCwoHknb)tjpl|_!zrY{hJ@_@e0k1#~E);n;Y;Qv) zh^Fg!TArJFSBzs^UN&t%$s7OIbTwn#u9K$$?G4%U?R7fd3RwCOGa=Tz@uzhj=JyG8zsrW`LM7e>D)Ke5o))nJs#n60|_*?aS-KX)+y)%+2^$B3^dHY>s6v=r`>aSK_U~k)h%7 z*=fW0tTQ;2vAvOS2Mwu96D&7IEyu&7Y?5>uO=mWkaD<66{)qp7BETF}RY^9hpgE%C zSz8y?F3w~fuv%%Gg~}hqPpPEv4g&vx_u(D*GdwJv*xG|oCGG-GswzwObH-*=gzX`! z18lFze}eU1?iNWW-kx>Fh)|R>uUaT;WOehBZNs(_%o0&M7mfutEi24QUUXw`j3%-P z$H=_JlJr{oDQadu>=|W3$@w=oxQ&sq=&;3=@g&LN^u}a@&R*c=g>6v%gkTA};s-%$ zm5yy@yNNCxynhOyB3MS?16VF~B|d{adhrB!UK^s)gU@?$F%I2%*}ffxUU(jkLwAw? zTh%TV1AyYySzDbutFxxG@YBaz;KhP;33Q`Ph;k7@#OHVUE9EbjfKeervb%gL$7_dV zYA+3VXCxM2*N-Gwr;nP&eUX6AZ1URzW-HwQ(z#~bPLCTOog8w{;kpLI@iIDmYBJZ5 z)#1Im>cb+es_VNv=aQ*u8oc98GyW*spmu|h{&7Pd=ioW_GZ*0sLopEQ$g=)aB+csZ z43iX0lk64r-G@(3c?yRyaI)Zw125<+Ut9y9`o*~NY(cgU?5J{2xuXmy&ldSV6*(O) zMS$Vt(*|`hF}&hgyz*AQsudWc;kaEZRL#RRuCvA+vu}l~1*;sc5xBmdik;PU_f?^U zP!%bE|05V^5%hK&fe+zr!5n3%?G!t~vlS{TKl}%DHlvkS55T{WV&W>?y~au6 z-)xH2!X?T^qLcTf>RX3z`9~$PbVXSgd`KAan}(mtg*HPQ kCvxEkH0`|U^V_%dJofm$=s{^2Uc*@k?^Hv6D5c!s4w-y<9RL6T diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..19c83e0 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,10 @@ +version: '4' + +services: + web: + build: . + command: gunicorn cookie_project.wsgi:application --bind 0.0.0.0:8000 --workers 4 + volumes: + - .:/code + ports: + - 8000:8000 \ No newline at end of file diff --git a/heroku.yml b/heroku.yml new file mode 100644 index 0000000..8f2bca6 --- /dev/null +++ b/heroku.yml @@ -0,0 +1,7 @@ +build: + docker: + web: Dockerfile +release: + image: web +run: + web: gunicorn cookie_project.wsgi --workers 4 \ No newline at end of file diff --git a/hospital/migrations/0003_alter_customuser_image.py b/hospital/migrations/0003_alter_customuser_image.py new file mode 100644 index 0000000..e6e0f89 --- /dev/null +++ b/hospital/migrations/0003_alter_customuser_image.py @@ -0,0 +1,18 @@ +# Generated by Django 4.0 on 2021-12-30 19:40 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('hospital', '0002_customuser_image'), + ] + + operations = [ + migrations.AlterField( + model_name='customuser', + name='image', + field=models.ImageField(upload_to='image'), + ), + ] diff --git a/hospital/migrations/0004_customuser_group.py b/hospital/migrations/0004_customuser_group.py new file mode 100644 index 0000000..35ef994 --- /dev/null +++ b/hospital/migrations/0004_customuser_group.py @@ -0,0 +1,21 @@ +# Generated by Django 4.0 on 2021-12-30 19:41 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('auth', '0012_alter_user_first_name_max_length'), + ('hospital', '0003_alter_customuser_image'), + ] + + operations = [ + migrations.AddField( + model_name='customuser', + name='group', + field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, related_name='boes2', to='auth.group'), + preserve_default=False, + ), + ] diff --git a/hospital/migrations/__pycache__/0001_initial.cpython-39.pyc b/hospital/migrations/__pycache__/0001_initial.cpython-39.pyc index 61bfd28af5ed65c24b6725b6ecef0bb89cf2b054..961711a1dfc84e36294202d00134bee79ff34cd5 100644 GIT binary patch delta 47 zcmZ3%F`0uqk(ZZ?0SKa*&u!%X$0X*jpOK%Ns$ZFyk(rp2n3S2MZ(?AmKiP!&3jium B4d(y= delta 68 zcmbQtv4Vp;k(ZZ?0SK1OJiC$mACq>9enx(7s(x;MMq+MmVv2r2QGQlxa!Ij%a(-!1 WacZ%?iGiVhT4r8ij_zc6<}U#3{udnp diff --git a/hospital/migrations/__pycache__/0002_customuser_image.cpython-39.pyc b/hospital/migrations/__pycache__/0002_customuser_image.cpython-39.pyc index bed21d127bca13040b33e2e4ac5531e0047401e1..2892c46e472da0b68d08594971159700a9f73f7e 100644 GIT binary patch delta 47 zcmeyv@|=Y`k(ZZ?0SKa*&u!$M#V8h`pOK%Ns$ZFyk(rp2n3S2MZ(?AmKluXV8UQ{T B4t)Rs delta 68 zcmaFP@`r^xk(ZZ?0SHXypWVnki%~mQKO;XkRX;aBBQZBOF-5Ilr{1 WIJH>c#K2HLEi*4MM|bjW#x(%%A{R#h diff --git a/hospital/migrations/__pycache__/__init__.cpython-39.pyc b/hospital/migrations/__pycache__/__init__.cpython-39.pyc index 7e3041990d96f5694a0aa8e14c972a2ff01c7190..b52345e5af74e972efe0ae6432e02561beccfbbc 100644 GIT binary patch delta 45 zcmdnZxQvlIk(ZZ?0SKa*&rRgE5%bp1$j?pHuT0FyOw374%1qKXF)-AhSmX%+1K|v% delta 66 zcmZ3+xSNqXk(ZZ?0SIO^o}I{Tqn)6ik)NBYpPQeNn46oJqF+#ypOu/", HospitalDetail.as_view(), name="hospital_detail"), - path('authenticate/', CustomObtainAuthToken.as_view()) + path('signup', CreateUserView.as_view(), name='signup'), + path("", HospitalDetail.as_view(), name="hospital_detail"), + path("auth/", CustomObtainAuthToken.as_view()) ] \ No newline at end of file diff --git a/hospital/views.py b/hospital/views.py index 7cefef0..f9179f8 100644 --- a/hospital/views.py +++ b/hospital/views.py @@ -5,7 +5,7 @@ from .serializers import UserSerializer from rest_framework_simplejwt.views import TokenObtainPairView from .serializers import MyTokenObtainPairSerializer - +from django.shortcuts import get_object_or_404 @@ -24,4 +24,7 @@ class HospitalDetail(RetrieveAPIView): serializer_class = UserSerializer permission_classes = [ permissions.AllowAny # Or anon users can't register - ] \ No newline at end of file + ] + def get_object(self): + UserName= self.kwargs.get("username") + return get_object_or_404(customUser, username=UserName) \ No newline at end of file diff --git a/lifeshare/urls.py b/lifeshare/urls.py index 779470f..965af18 100644 --- a/lifeshare/urls.py +++ b/lifeshare/urls.py @@ -23,8 +23,8 @@ urlpatterns = [ path('admin/', admin.site.urls), - path('api/v1/add/',include('accounts.urls')), - path('api/token/', jwt_views.TokenObtainPairView.as_view(), name='token_obtain_pair'), + path('account/',include('accounts.urls')), + path('api/token/', jwt_views.TokenObtainPairView.as_view(), name='token_obtain_pair'), path('api/token/refresh/', jwt_views.TokenRefreshView.as_view(), name='token_refresh'), path('hospital/', include('hospital.urls')), ] diff --git a/templates/base.html b/templates/base.html deleted file mode 100644 index ec94dd0..0000000 --- a/templates/base.html +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - {% block title %}Django Auth Tutorial{% endblock %} - - -
- {% block content %} - {% endblock %} -
- - \ No newline at end of file diff --git a/templates/registration/signup.html b/templates/registration/signup.html deleted file mode 100644 index 404a990..0000000 --- a/templates/registration/signup.html +++ /dev/null @@ -1,13 +0,0 @@ - -{% extends 'base.html' %} - -{% block title %}Sign Up{% endblock %} - -{% block content %} -

Sign up

-
- {% csrf_token %} - {{ form.as_p }} - -
-{% endblock %} \ No newline at end of file diff --git a/views.py b/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here.