Skip to content

Commit dbd4ec8

Browse files
author
Nicholas
authored
Graphql organizations resolvers (canada-ca#98)
* Auto gen of enums now include descriptions * Added check to get enums from Azure when testing
1 parent d9f3f32 commit dbd4ec8

7 files changed

Lines changed: 364 additions & 9 deletions

File tree

api/functions/generate_enums.py

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import graphene
2+
import enum
23
from sqlalchemy.orm import load_only
34
from model_enums import create_enum_app, create_enum_db
45
from models import (
@@ -40,9 +41,54 @@ def create_enums(Table, enum_name, column):
4041
enum_dict.update({select[1]: select[1]})
4142

4243
if not len(enum_dict):
43-
return graphene.Enum(enum_name, 'EMPTY')
44+
ret_enum = enum.Enum(enum_name, 'EMPTY')
4445
else:
45-
return graphene.Enum(enum_name, enum_dict)
46+
ret_enum = enum.Enum(enum_name, enum_dict)
47+
48+
return graphene.Enum.from_enum(ret_enum)
49+
50+
51+
def create_enum_with_descriptions(Table, enum_name, enum_column, description_column):
52+
"""
53+
Function to allow the creation of enums with descriptions for various uses. Function takes in SQLAlchemy Model,
54+
and the Column that you would like your enums to be created. The value of the enum is equal to that of the name
55+
"""
56+
app = create_enum_app()
57+
db = create_enum_db(app)
58+
59+
with app.app_context():
60+
query = db.session.query(Table).options(load_only(enum_column))
61+
rows = db.session.execute(query).fetchall()
62+
63+
enum_dict = dict()
64+
65+
for select in rows:
66+
enum_dict.update({select[1]: select[1]})
67+
68+
if not len(enum_dict):
69+
ret_enum = enum.Enum(enum_name, 'EMPTY')
70+
else:
71+
ret_enum = enum.Enum(enum_name, enum_dict)
72+
73+
description_dict = dict()
74+
75+
for e in ret_enum:
76+
with app.app_context():
77+
query = db.session.query(Table).filter(getattr(Table, enum_column) == e.name).options(load_only(description_column))
78+
row = db.session.execute(query).first()
79+
80+
try:
81+
description_dict.update({e.name: row[1]})
82+
except:
83+
description_dict.update({e.name: "Error loading description"})
84+
85+
@property
86+
def description(self):
87+
return description_dict.get(self.name)
88+
89+
setattr(ret_enum, 'description', description)
90+
91+
return graphene.Enum.from_enum(ret_enum)
4692

4793
# Example of how to create enums for a given table
4894
# from functions.generate_enums import create_enums

api/model_enums/organiztions.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
from models import Organizations
2+
from functions.generate_enums import create_enum_with_descriptions
3+
4+
OrganizationsEnum = create_enum_with_descriptions(Organizations, 'OrganizationsEnum', 'organization', 'description')

api/queries.py

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@
77

88
from model_enums.sectors import SectorEnums, ZoneEnums
99
from model_enums.groups import GroupEnums
10+
from model_enums.organiztions import OrganizationsEnum
1011

1112
from schemas.user import *
1213

1314
from schemas.sectors import Sectors
1415
from schemas.groups import Groups
16+
from schemas.organizations import Organizations
1517

1618

1719
from resolvers.sectors import (
@@ -26,6 +28,12 @@
2628
resolve_get_group_by_sector
2729
)
2830

31+
from resolvers.organizations import (
32+
resolve_get_org_by_id,
33+
resolve_get_org_by_org,
34+
resolve_get_orgs_by_group
35+
)
36+
2937

3038
class Query(graphene.ObjectType):
3139
"""The central gathering point for all of the GraphQL queries."""
@@ -54,7 +62,7 @@ class Query(graphene.ObjectType):
5462
)
5563
get_group_by_id = graphene.List(
5664
of_type=Groups,
57-
id=graphene.Argument(graphene.Int, required=False),
65+
id=graphene.Argument(graphene.Int, required=True),
5866
resolver=resolve_get_group_by_id,
5967
description="Allows selection of a group from a given group ID"
6068
)
@@ -70,6 +78,24 @@ class Query(graphene.ObjectType):
7078
resolver=resolve_get_group_by_sector,
7179
description="Allows selection of groups from a given sector enum"
7280
)
81+
get_org_by_id = graphene.List(
82+
of_type=Organizations,
83+
id=graphene.Argument(graphene.Int, required=True),
84+
resolver=resolve_get_org_by_id,
85+
description="Allows the selection of an organization from a given ID"
86+
)
87+
get_org_by_org = graphene.List(
88+
of_type=Organizations,
89+
org=graphene.Argument(OrganizationsEnum, required=True),
90+
resolver=resolve_get_org_by_org,
91+
description="Allows the selection of an organization from its given organization code"
92+
)
93+
get_org_by_group = graphene.List(
94+
of_type=Organizations,
95+
group=graphene.Argument(GroupEnums, required=True),
96+
resolver=resolve_get_orgs_by_group,
97+
description="Allows the selection of organizations from a given group"
98+
)
7399

74100
generate_otp_url = String(email=String(required=True))
75101

api/resolvers/organizations.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
from graphql import GraphQLError
2+
from sqlalchemy.orm import load_only
3+
4+
from schemas.organizations import (
5+
Organizations,
6+
OrganizationsModel
7+
)
8+
9+
from schemas.groups import (
10+
Groups,
11+
GroupsModel
12+
)
13+
14+
15+
# Resolvers
16+
def resolve_get_org_by_id(self, info, **kwargs):
17+
"""Return an organization by its id"""
18+
org_id = kwargs.get('id')
19+
query = Organizations.get_query(info).filter(
20+
OrganizationsModel.id == org_id
21+
)
22+
if not len(query.all()):
23+
raise GraphQLError("Error, Invalid ID")
24+
return query.all()
25+
26+
27+
def resolve_get_org_by_org(self, info, **kwargs):
28+
"""Return an organization by its organization code"""
29+
org_code = kwargs.get('org')
30+
query = Organizations.get_query(info).filter(
31+
OrganizationsModel.organization == org_code
32+
)
33+
if not len(query.all()):
34+
raise GraphQLError("Error, Invalid Organization")
35+
return query.all()
36+
37+
38+
def resolve_get_orgs_by_group(self, info, **kwargs):
39+
group = kwargs.get('group')
40+
group_id = Groups.get_query(info).filter(
41+
GroupsModel.s_group == group
42+
).options(load_only('id'))
43+
44+
if not len(group_id.all()):
45+
raise GraphQLError("Error, no group associated with that enum")
46+
47+
query = Organizations.get_query(info).filter(
48+
OrganizationsModel.group_id == group_id
49+
)
50+
51+
if not len(query.all()):
52+
raise GraphQLError("Error, no organizations associated with that group")
53+
return query.all()

api/tests/test_groups_resolver.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77

88
from unittest import TestCase
99

10+
import model_enums
11+
model_enums._called_from_test = True
12+
1013
from app import app
1114
from db import db
1215
from models import Sectors, Groups
@@ -23,6 +26,9 @@ def group_test_resolver_db_init():
2326
"""Build database for group resolver testing"""
2427
db.init_app(app)
2528

29+
sector_added = False
30+
group_added = False
31+
2632
with app.app_context():
2733
if Sectors.query.first() is None:
2834
sector = Sectors(
@@ -33,6 +39,7 @@ def group_test_resolver_db_init():
3339
)
3440
db.session.add(sector)
3541
db.session.commit()
42+
sector_added = True
3643

3744
if Groups.query.first() is None:
3845
group = Groups(
@@ -43,14 +50,17 @@ def group_test_resolver_db_init():
4350
)
4451
db.session.add(group)
4552
db.session.commit()
53+
group_added = True
4654

47-
yield
55+
yield
4856

49-
with app.app_context():
50-
Groups.query.filter(Groups.id == 1).delete()
51-
db.session.commit()
52-
Sectors.query.filter(Sectors.id == 1).delete()
53-
db.session.commit()
57+
with app.app_context():
58+
if group_added:
59+
Groups.query.filter(Groups.id == 1).delete()
60+
db.session.commit()
61+
if sector_added:
62+
Sectors.query.filter(Sectors.id == 1).delete()
63+
db.session.commit()
5464

5565

5666
@pytest.mark.usefixtures('group_test_resolver_db_init')

0 commit comments

Comments
 (0)