Created
April 21, 2020 10:57
-
-
Save Tushant/ef37f99d70eee1d913fc38d9c4e23d44 to your computer and use it in GitHub Desktop.
Ariadne Modularization
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
graphapi | |
__init__.py | |
scalar.py | |
schema.py | |
utils.py | |
accounts | |
__init__.py | |
resolvers.py | |
schema.graphql | |
products | |
__init__.py | |
resolvers.py | |
schema.graphql |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# products/resolvers.py | |
from ariadne import ( | |
QueryType, | |
MutationType, | |
) | |
from products.models import Product | |
query = QueryType() | |
mutation = MutationType() | |
@query.field('products') | |
def resolve_products(obj, info): | |
return Product.objects.all() | |
resolvers = [query, mutation] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# accounts/resolvers.py | |
from ariadne import (QueryType, MutationType) | |
from django.contrib.auth import get_user_model | |
from django.conf import settings | |
from django.contrib.auth.tokens import default_token_generator | |
from django.contrib.auth import password_validation | |
from django.core.exceptions import ValidationError | |
from accounts import emails | |
query = QueryType() | |
mutation = MutationType() | |
User = get_user_model() | |
@query.field('users') | |
def resolve_users(obj, info): | |
return User.objects.all() | |
@mutation.field('signup') | |
def resolve_signup(obj, info, input): | |
first_name, last_name, email, password = (input['firstName'], input['lastName'], input['email'], input['password']) | |
User = get_user_model() | |
if not User.objects.filter(email=email).exists(): | |
user = User.objects.create_user(email, password) | |
if settings.ENABLE_ACCOUNT_CONFIRMATION_BY_EMAIL: | |
user.is_active = False | |
user.save() | |
emails.send_account_confirmation_email(user, input['redirectURI']) | |
user.profile.first_name=first_name | |
user.profile.last_name=last_name | |
user.profile.save() | |
# there can be better way of handling responses | |
return {'status': 200, 'success': True, 'message': 'User account created'} | |
else: | |
return {'status': 500, 'success': False, 'message': 'Username with that email or password already exists'} | |
@mutation.field('confirmAccount') | |
def resolve_confirm_account(obj, info, input): | |
email, token = (input['email'], input['token']) | |
User = get_user_model() | |
try: | |
user = User.objects.get(email=email) | |
except User.DoesNotExist: | |
return {'status': 500, 'success': False, 'message': "User with this email doesn't exist"} | |
if not default_token_generator.check_token(user, input['token']): | |
return {'status': 500, 'success': False, 'message': 'Invalid token'} | |
user.is_active = True | |
# user.is_email_verified = True | |
user.save(update_fields=["is_active"]) | |
return {'status': 200, 'success': True, 'message': "User's email activated"} | |
@mutation.field('login') | |
def resolve_login(obj, info, input): | |
return {'status': 200, 'success': True, 'message': 'login succeed', token: 'afsdufsk'} | |
@mutation.field('requestPasswordRequest') | |
def resolve_request_password_request(obj, info, input): | |
email, redirect_url = (input['email'], input['redirectURI']) | |
try: | |
user = User.objects.get(email=email) | |
except: | |
return {'status': 500, 'success': False, 'message': "User with this email doesn't exist"} | |
emails.send_user_password_reset_email_with_url(user, redirect_url) | |
return {'status': 200, 'success': True, 'message': 'Email sent to reset your password'} | |
@mutation.field('setPassword') | |
def resolve_set_password(obj, info, input): | |
email, password, token = (input['email'], input['password'], input['token']) | |
try: | |
user = User.objects.get(email=email) | |
except User.DoesNotExist: | |
return {'status': 500, 'success': False, 'message': "User with this email doesn't exist"} | |
if not default_token_generator.check_token(user, token): | |
return {'status': 500, 'success': False, 'message': "Invalid token"} | |
try: | |
password_validation.validate_password(password, user) | |
except ValidationError as error: | |
# need a way to send error to client | |
print("error ------->", error) | |
return {'status': 500, 'success': False, 'message': error} | |
# raise ValidationError({"password": error}) | |
user.set_password(password) | |
user.save(update_fields=["password"]) | |
return {'status': 200, 'success': True, 'message': "Password changed successfully"} | |
@mutation.field('changePassword') | |
def resolve_change_password(obj, info, input): | |
import pdb; pdb.set_trace() | |
user = info.context.user | |
if user.is_authenticated: | |
old_password, new_password = (input['oldPassword'], input['newPassword']) | |
if not user.check_password(old_password): | |
return {'status': 500, 'success': False, 'message': 'Old password is not valid'} | |
try: | |
password_validation.validate_password(new_password, user) | |
except ValidationError as error: | |
raise ValidationError({"new_password": error}) | |
user.set_password(new_password) | |
user.save(update_fields=['password']) | |
return {'status': 200, 'success': True, 'message': 'Changed password successfully'} | |
else: | |
return {'status': 500, 'success': False, 'message': 'User is not authenticated'} | |
resolvers = [query, mutation] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# products/schema.graphql | |
extend type Query { | |
products: [Product] | |
} | |
type Product { | |
name: String! | |
slug: String! | |
description: String! | |
price: String! | |
isAvailable: Boolean! | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# accounts/schema.graphql | |
type Query { | |
users: [User]! | |
} | |
type Mutation { | |
signup(input: SignupUser!): SignupResponse! | |
confirmAccount(input: ConfirmAccount!): SignupResponse! | |
login(input: LoginUser!): TokenResponse! | |
requestPasswordRequest(input: RequestPasswordReset!): SignupResponse! | |
setPassword(input: SetPassword!): SignupResponse! | |
changePassword(input: PasswordChange!): SignupResponse! | |
} | |
# global response is better i think which will be resuable to all the modules | |
interface Response { | |
status: Int! | |
success: Boolean! | |
message: String! | |
} | |
# status, success, message is repeating most of the times | |
type SignupResponse implements Response { | |
status: Int! | |
success: Boolean! | |
message: String! | |
} | |
type TokenResponse implements Response { | |
status: Int! | |
success: Boolean! | |
message: String! | |
token: String | |
} | |
type User { | |
email: String! | |
} | |
input SignupUser { | |
firstName: String! | |
lastName: String! | |
email: String! | |
password: String! | |
redirectURI: String! | |
} | |
input LoginUser { | |
email: String! | |
password: String! | |
} | |
input ConfirmAccount { | |
token: String! | |
email: String! | |
} | |
input RequestPasswordReset { | |
email: String! | |
redirectURI: String | |
} | |
input SetPassword { | |
email: String! | |
password: String! | |
token: String! | |
} | |
input PasswordChange { | |
oldPassword: String! | |
newPassword: String! | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from ariadne import QueryType, load_schema_from_path, make_executable_schema | |
from graphapi.accounts.resolvers import resolvers as accounts_resolvers | |
from graphapi.products.resolvers import resolvers as products_resolvers | |
# from graphql import (query, mutation) | |
product_type_defs = load_schema_from_path('graphapi/products/schema.graphql') | |
account_type_defs = load_schema_from_path('graphapi/accounts/schema.graphql') | |
query = QueryType() | |
type_defs = [product_type_defs, account_type_defs] | |
resolvers = [query] | |
resolvers += accounts_resolvers | |
resolvers += products_resolvers | |
# resolvers = [query, accounts_resolvers, products_resolvers] | |
schema = make_executable_schema(type_defs, resolvers) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi,
How do you load the scalars from the scalar.py file ?