Skip to content

Instantly share code, notes, and snippets.

@Tushant
Created April 21, 2020 10:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Tushant/ef37f99d70eee1d913fc38d9c4e23d44 to your computer and use it in GitHub Desktop.
Save Tushant/ef37f99d70eee1d913fc38d9c4e23d44 to your computer and use it in GitHub Desktop.
Ariadne Modularization
graphapi
__init__.py
scalar.py
schema.py
utils.py
accounts
__init__.py
resolvers.py
schema.graphql
products
__init__.py
resolvers.py
schema.graphql
# 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]
# 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]
# products/schema.graphql
extend type Query {
products: [Product]
}
type Product {
name: String!
slug: String!
description: String!
price: String!
isAvailable: Boolean!
}
# 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!
}
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)
@kleysonr
Copy link

kleysonr commented May 2, 2020

Hi,

How do you load the scalars from the scalar.py file ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment