class UserMetaResource(WigoResource): model = User @user_token_required @api.response(200, 'Success', model=api.model( 'UserMeta', { 'last_message_received': fields.DateTime(), 'last_friend_request': fields.DateTime(), 'last_notification': fields.DateTime(), 'is_tapped': fields.Boolean(), 'is_friend': fields.Boolean(), 'is_blocked': fields.Boolean(), 'attending_event_id': fields.Integer(), 'friend_request': fields.String(), 'num_friends_in_common': fields.Integer() })) def get(self, user_id): user_id = self.get_id(user_id) meta = {} if user_id == g.user.id: user_meta = wigo_db.get_redis().hgetall( skey('user', user_id, 'meta')) if user_meta: def format_date(field): return datetime.utcfromtimestamp(float( user_meta[field])).isoformat() if 'last_message_received' in user_meta: meta['last_message_received'] = format_date( 'last_message_received') if 'last_friend_request' in user_meta: meta['last_friend_request'] = format_date( 'last_friend_request') if 'last_notification' in user_meta: meta['last_notification'] = format_date( 'last_notification') meta['attending_event_id'] = g.user.get_attending_id() else: meta['is_tapped'] = g.user.is_tapped(user_id) meta['is_friend'] = g.user.is_friend(user_id) meta['is_blocked'] = g.user.is_blocked(user_id) if g.user.is_friend_request_sent(user_id): meta['friend_request'] = 'sent' elif g.user.is_friend_request_received(user_id): meta['friend_request'] = 'received' if request.args.get('num_friends_in_common') == 'true': meta['num_friends_in_common'] = len( g.user.get_friend_ids_in_common(user_id)) meta['num_friends'] = wigo_db.get_sorted_set_size( skey('user', user_id, 'friends')) return meta
def paginate_events(self): return self.api.model( 'EventsAsistances', { 'page': fields.Integer(required=False), 'totalPages': fields.Integer(required=False), 'events': fields.List(fields.Nested(self.event, required=False)) })
def paginate_assistances(self): return self.api.model( 'PaginateAsistances', { 'page': fields.Integer(required=False), 'totalPages': fields.Integer(required=False), 'assistances': fields.List( fields.Nested(self.assistance, required=False, description='Requerimientos')) })
class UserReferredResource(WigoResource): model = User @user_token_required @api.expect( api.model( 'Referred', { 'referred_by_id': fields.Integer(description='User who referred user_id', required=True) })) @api.response(200, 'Success') def post(self, user_id): referred_by_id = self.get_id_field('referred_by_id') referred_by = User.find(referred_by_id) referred_key = skey(referred_by, 'referred') # record into the referrers list of users they referred if not wigo_db.sorted_set_is_member(referred_key, g.user.id): wigo_db.sorted_set_add(referred_key, g.user.id, time()) # record into the referrers rankings for the month now = datetime.now(Configuration.ANALYTICS_TIMEZONE) wigo_db.sorted_set_incr_score( skey('referrers', now.month, now.year), referred_by.id) wigo_db.sorted_set_incr_score(skey('referrers'), referred_by.id) return {'success': True}
class BlockListResource(WigoResource): model = Block @user_token_required @check_last_modified('user', 'last_block_change') @api.response(200, 'Success') def get(self, user_id, headers): return g.user.get_blocked_ids(), 200, headers @user_token_required @api.expect( api.model( 'NewBlock', { 'blocked_id': fields.Integer(description='User to block', required=True), 'type': fields.String( description= 'The block type, "abusive" is only supported value') })) @api.response(200, 'Success') def post(self, user_id): block = Block() block.user_id = g.user.id block.blocked_id = self.get_id_field('blocked_id') block.type = request.get_json().get('type') block.save() return {'success': True}
def test_integer_field_with_description(self): field = fields.Integer(description='A description') self.assertFalse(field.required) self.assertEqual(field.__schema__, { 'type': 'integer', 'description': 'A description' })
def test_integer_field_with_title(self): field = fields.Integer(title='A title') self.assertFalse(field.required) self.assertEqual(field.__schema__, { 'type': 'integer', 'title': 'A title' })
def test_integer_field_with_readonly(self): field = fields.Integer(readonly=True) self.assertFalse(field.required) self.assertEqual(field.__schema__, { 'type': 'integer', 'readOnly': True })
def test_integer_field_with_min_max(self): field = fields.Integer(min=0, max=5) self.assertFalse(field.required) self.assertEqual(field.__schema__, { 'type': 'integer', 'minimum': 0, 'maximum': 5 })
def create_requirement(self): return self.api.model( 'Requirement', { 'name': fields.String(required=True, description='Event name'), 'quantity': fields.Integer(required=True, description='Name of event') })
def create_event(self): requirement = self.api.model( 'Requirement', { 'name': fields.String(required=True, description='Event name'), 'quantity': fields.Integer(required=True, description='Name of event') }) event = self.api.model( 'Event', { 'tag': fields.String(required=False, description='Tag of event'), 'name': fields.String(required=True, description='Name of event'), 'date': fields.String(required=True, description='Date of event' ), # Cambiar el type por lo que corresponde. 'time': fields.String(required=False, description='Time of event'), 'capacity': fields.String(required=False, description='Capacity of event'), 'venue': fields.Nested(self.venueDocument.venue, required=False, description='Venue of event'), 'image': fields.String(required=False, description='Image of event'), 'description': fields.String(required=False, description='Description of event'), 'visibility': fields.String(required=True, description='Visibility of event'), 'hasAssistance': fields.Boolean(required=False, description=''), 'isOwner': fields.Boolean(required=False, description=''), 'soldOut': fields.Boolean(required=False, description=''), 'gests': fields.List(fields.String(), required=False, description='Description of event'), 'requirementMissing': fields.List(fields.Nested(requirement), required=False, description='Requirements missing'), 'requirement': fields.List(fields.Nested(requirement), required=False, description='Requirements') }) return event
class TapListResource(WigoResource): model = Tap @user_token_required @check_last_modified('user', 'last_tap_change') @api.response(200, 'Success') def get(self, user_id, headers): return g.user.get_tapped_ids(), 200, headers @user_token_required @api.expect( api.model('NewTap', { 'tapped_id': fields.Integer(description='User to tap', required=True) })) @api.response(200, 'Success') @api.response(403, 'Not friends') def post(self, user_id): tap = Tap() tap.user_id = g.user.id tap.tapped_id = self.get_id_field('tapped_id') tap.save() return {'success': True}
class VertexUpdate(Resource): vertexUpdate = api.model( 'VertexUpdate', { 'vertex': fields.String(required=True, description='Vertex Name'), 'vtype': fields.String(required=True, description='Vertex Type Name (None = 0)'), 'set_weight': fields.String(required=False, description='Edge type'), 'incr_weight': fields.Integer(required=False, description='Timestamp') }) vertexUpdateSpec = api.model( 'Update', { 'vertexUpdates': fields.List(fields.Nested(vertexUpdate), description='List of Vertex Updates', required=True), 'immediate': fields.Boolean( description= 'Instructs the API to send this batch to STINGER immediately upon receipt', required=False, default=False) }) @api.expect(vertexUpdateSpec) @api.doc( responses={ 201: 'Vertices Updated', 400: 'Bad Request', 503: 'Unable to reach STINGER' }) def post(self): exec_time = time.time() if not request.json: r = json.dumps({"error": "Invalid input"}) return Response(response=r, status=400, mimetype="application/json") # grab the lock counter_lock.acquire() try: data = request.json send_immediate = False if 'immediate' in data: if data['immediate'] == True: send_immediate = True if isinstance(data["vertexUpdates"], list): vertexUpdates = data["vertexUpdates"] print "Received batch of size", len( vertexUpdates), 'at', strftime("%Y%m%d%H%M%S", gmtime()), "" for x in vertexUpdates: try: vtx = str(x["vertex"]) vtype = str(x["vtype"]) set_weight = x["set_weight"] if 'set_weight' in x else 0 incr_weight = int( x["incr_weight"]) if 'incr_weight' in x else 0 s.add_vertex_update(vtx, vtype, set_weight, incr_weight) except Exception as e: print(traceback.format_exc()) pass # send immediately if the batch is now large current_batch_size = s.insertions_count + s.deletions_count + s.vertex_updates_count if current_batch_size > BATCH_THRESHOLD and BATCH_THRESHOLD > 0 or send_immediate: print "Sending batch of size", current_batch_size, 'at', strftime( "%Y%m%d%H%M%S", gmtime()), "" s.send_batch() except: print(traceback.format_exc()) r = json.dumps({"error": "Unable to parse object"}) return Response(response=r, status=400, mimetype="application/json") # end critical section finally: counter_lock.release() exec_time = time.time() - exec_time r = json.dumps({ "status": "success", "time": exec_time, "current_batch_size": current_batch_size }) return Response(response=r, status=201, mimetype="application/json")
def get(self): args = _filter_parser.parse_args() group_by = args['group_by'].split(',') group_by_fields = [] # Always return a count query_args = [func.count(Contrato.id).label('count')] keys = [] temporary_keys = [] partial_fields = [] # Tuples with SQLAlchemy function and args to get parts of values. # This allows to group by years or months for example. parts = { 'year': (lambda field: [func.extract('year', field)], lambda values: list(values)[0]), 'month': (lambda field: [ func.extract('year', field), func.extract('month', field), ], lambda values: '-'.join([format(v, '02') for v in values])), 'day': (lambda field: [ func.extract('year', field), func.extract('month', field), func.extract('day', field), ], lambda values: '-'.join([format(v, '02') for v in values])), } for field_name in group_by: part = None if field_name.endswith( tuple(map(lambda a: '__{}'.format(a), parts.keys()))): # User asked to group using only part of value. # Get the original field name and which part we should use. # "?group_by=data_publicacao__year" results in # field_name = 'data_publicacao' # part = 'year' field_name, part = field_name.split('__', 1) if field_name in contratos_fields: group_by_field = [getattr(Contrato, field_name)] if part: # Apply the "part" function group_by_field = parts[part][0](group_by_field[0]) temporary_keys.extend([ '{}__{}'.format(field_name, i) for i in range(len(group_by_field)) ]) partial_fields.append({ 'field_name': field_name, 'count': len(group_by_field), 'part_name': part, }) else: keys.append(field_name) temporary_keys.append(field_name) group_by_fields.extend(group_by_field) query_args.extend(group_by_field) query_args.append(func.sum(Contrato.valor).label('valor')) keys.append('valor') temporary_keys.append('valor') contratos_data = db.session.query(*query_args) if group_by_fields: contratos_data = contratos_data.group_by(*group_by_fields) contratos_data = self.order(contratos_data) contratos_data = self.filter(contratos_data) total_count = contratos_data.count() contratos_data = self.paginate(contratos_data) headers = { # Add 'Access-Control-Expose-Headers' header here is a workaround # until Flask-Restful adds support to it. 'Access-Control-Expose-Headers': 'X-Total-Count', 'X-Total-Count': total_count } # Create the dictionary used to marshal fields_ = {'count': fields.Integer()} fields_.update( {key: contratos_fields.get(key, fields.String()) for key in keys}) # Create a list of dictionaries result = map(lambda a: dict(zip(['count'] + temporary_keys, a)), contratos_data.all()) # Set partial dates type to string for f in partial_fields: fields_[f['field_name']] = fields.String() for item in result: item[f['field_name']] = parts[f['part_name']][1]( (item.pop('{}__{}'.format(f['field_name'], i)) for i in range(f['count']))) return restful.marshal(result, fields_), 200, headers
app = Flask(__name__) api = Api(app, version='1.0', title='Resume Generator API', description='An API used to integrate resume information from various formats and transform them into different graphical representations.') ns = api.namespace('resumes', description='Resumes') resume_parser = api.parser() resume_parser.add_argument('username', type=str, required=True, help='Your username, used as an identifier for any request to the API', location='form') resume_parser.add_argument('fullname', type=str, required=True, help='Your full name', location='form') resume_parser.add_argument('age', type=int, required=True, help='Your age', location='form') resume = api.model('Resume', { 'username': fields.String(required=True), 'fullname': fields.String(required=True), 'age' : fields.Integer(required=True) }) SUPPORTED_INPUTS = ['json'] resume_content_parser = api.parser() resume_content_parser.add_argument('content', type=str, required=True, help='The resume content in the format described by content_type.', location='form') resume_content_parser.add_argument('content_type', type=str, required=True, help='The resume content type submitted. Currently supported: ' + ', '.join(SUPPORTED_INPUTS), location='form') resume_content = api.model('ResumeContent', { 'content' : fields.String(required=True), 'content_type' : fields.String(required=True, enum=SUPPORTED_INPUTS), }) SUPPORTED_VIEWS = ['kibana3']
def test_integer_field_with_required(self): field = fields.Integer(required=True) self.assertTrue(field.required) self.assertEqual(field.__schema__, {'type': 'integer'})
class FriendsListResource(WigoResource): model = Friend @user_token_required @check_last_modified('user', 'last_friend_change') @api.response(200, 'Success', model=User.to_doc_list_model(api)) def get(self, user_id, headers): user = User.find(self.get_id(user_id)) text = request.args.get('text') if text: sql = """ select users.id from data_int_sorted_sets inner join users on users.key = format('{{user:%%s}}', data_int_sorted_sets.value) where data_int_sorted_sets.key = '{{user:{}}}:friends' """.format(user.id) params = [] split = [('{}%%'.format(part)) for part in re.split(r'\s+', text.strip().lower())] for s in split: sql += "AND ((LOWER(first_name) LIKE %s) or " \ "(LOWER(last_name) LIKE %s))" params.append(s) params.append(s) sql += "ORDER BY first_name, last_name" with slave.execution_context(False) as ctx: results = list(slave.execute_sql(sql, params)) users = User.find([id[0] for id in results]) if g.user == user: for friend in users: friend.friend = True else: for friend, is_friend in g.user.are_friends(users).items(): friend.friend = is_friend return self.serialize_list(self.model, users), 200, headers else: query = self.select(User).user(user).friends() count, page, users = query.execute() if g.user == user: for friend in users: friend.friend = True else: for friend, is_friend in g.user.are_friends(users).items(): friend.friend = is_friend return self.serialize_list(User, users, count, page), 200, headers @user_token_required @api.expect( api.model( 'NewFriend', { 'friend_id': fields.Integer(description='User to connect with', required=True) })) @api.response(200, 'Success') def post(self, user_id): friend_id = self.get_id_field('friend_id') # check if already friends, or friend request already sent if g.user.is_friend(friend_id) or g.user.is_friend_request_sent( friend_id): return {'success': True, 'status': 'already_friends'} friend = Friend() friend.user_id = g.user.id friend.friend_id = friend_id friend.save() return {'success': True} @user_token_required @api.expect( api.model( 'DeleteFriend', { 'friend_id': fields.Integer(description='User to remove connection with', required=True) })) @api.response(200, 'Success') def delete(self, user_id): Friend({ 'user_id': g.user.id, 'friend_id': self.get_id_field('friend_id') }).delete() return {'success': True}
class InviteListResource(WigoResource): model = Invite @user_token_required @api.response(200, 'Success', model=User.to_doc_list_model(api)) def get(self, event_id): event = Event.find(event_id) page = self.get_page() limit = self.get_limit() start = (page - 1) * limit num_friends = wigo_db.get_sorted_set_size(skey(g.user, 'friends')) # find the users top 5 friends. this is users with > 3 interactions top_5 = wigo_db.sorted_set_rrange_by_score(skey( g.user, 'friends', 'top'), 'inf', 3, limit=5) if not top_5: top_5 = wigo_db.sorted_set_rrange_by_score(skey(g.user, 'friends'), 'inf', 3, limit=5) friend_ids = wigo_db.sorted_set_range(skey(g.user, 'friends', 'alpha'), start, start + (limit - 1)) for top_friend_id in top_5: if top_friend_id in friend_ids: friend_ids.remove(top_friend_id) if page == 1 and top_5: friend_ids = top_5 + friend_ids users = User.find(friend_ids) p = wigo_db.redis.pipeline() for user in users: p.zscore(skey(event, g.user, 'invited'), user.id if user else -1) scores = p.execute() for index, user in enumerate(users): if user: user.invited = scores[index] is not None return self.serialize_list(self.model, users, num_friends, page) @user_token_required @api.expect( api.model( 'NewInvite', { 'invited_id': fields.Integer(description='User to invite', required=True), })) @api.response(200, 'Success') @api.response(403, 'Not friends or not attending') def post(self, event_id): user = g.user if 'friends' in request.get_json(): from server.tasks.data import send_friend_invites num_friends = wigo_db.get_sorted_set_size(skey(user, 'friends')) if num_friends < 25: send_friend_invites(user.id, event_id) else: send_friend_invites.delay(user.id, event_id) else: invite = Invite() invite.user_id = user.id invite.invited_id = self.get_id_field('invited_id') invite.event_id = event_id invite.save() return {'success': True}
_query_parser.add_argument('fuzzy', type=bool, default=False) _query_parser.add_argument('highlight', type=bool, default=False) _query_parser.add_argument('query') list_parser = api.parser() for arg in _filter_parser.args + _order_by_parser.args + _pagination_parser.args: list_parser.add_argument(arg) search_parser = api.parser() for arg in _filter_parser.args + _order_by_parser.args + _pagination_parser.args + _query_parser.args: search_parser.add_argument(arg) # Fields for ContratoAPI data marshal contratos_fields = { 'id': fields.Integer(description='O número identificador único de um contrato'), 'orgao': fields.String(description='Órgão'), 'data_assinatura': fields.DateTime(dt_format='iso8601'), 'vigencia': fields.Integer(), 'objeto': fields.String(description='Texto que aparece na descricao do contrato'), 'modalidade': fields.String(description='e.g. Pregão'), 'evento': fields.String(), 'processo_administrativo': fields.String(), 'cnpj':
def test_with_default(self): field = fields.Integer(default=42) self.assertFalse(field.required) self.assertEqual(field.__schema__, {'type': 'integer', 'default': 42})
'configuration details Model for collectd', { 'LogstashIP': fields.String(required=True, default='127.0.0.1', description='IP of the Logstash Server'), 'UDPPort': fields.String(required=True, default='25680', description='Port of UDP plugin from Logstash Server'), 'Interval': fields.String(required=False, default='15', description='Polling interval for all resources'), 'Cassandra': fields.Integer( required=False, default=0, description='Configure GenericJMX for cassandra monitoring'), 'MongoDB': fields.Integer( required=False, default=0, description='Configure collectd for MongoDB monitoring'), 'MongoHost': fields.String(required=False, default='127.0.0.1', description='Configure MongoDBHost'), 'MongoDBPort': fields.String(required=False, default='27017', description='Configure MongoDBPort'), 'MongoDBUser':
class Insert(Resource): edge = api.model( 'Edge', { 'src': fields.String(required=True, description='Source vertex'), 'dest': fields.String(required=True, description='Destination vertex'), 'type': fields.String(required=False, description='Edge type'), 'weight': fields.Integer(required=False, description='Edge weight'), 'time': fields.Integer(required=False, description='Timestamp') }) edgesSpec = api.model( 'Insert', { 'edges': fields.List(fields.Nested(edge), description='List of edges', required=True), 'immediate': fields.Boolean( description= 'Instructs the API to send this batch to STINGER immediately upon receipt', required=False, default=False), 'strings': fields.Boolean( description= 'Instructs the API to interpret integer vertex names as strings rather than integer vertex IDs', required=False, default=True) }) @api.expect(edgesSpec) @api.doc(responses={ 201: 'Edge Inserted', 400: 'Bad Request', 503: 'Unable to reach STINGER' }) def post(self): setupSTINGERConnection() exec_time = time.time() if not request.json: r = json.dumps({"error": "Invalid input"}) return Response(response=r, status=400, mimetype="application/json") # grab the lock counter_lock.acquire() try: data = request.json send_immediate = False if 'immediate' not in data else data[ 'immediate'] only_strings = True if 'strings' not in data else data['strings'] if isinstance(data["edges"], list): edges = data["edges"] print "Received batch of size", len(edges), 'at', strftime( "%Y%m%d%H%M%S", gmtime()), "" for x in edges: try: if only_strings: source = str(x["src"]) destination = str(x["dest"]) else: source = x["src"] destination = x["dest"] edge_type = x["type"] if 'type' in x else 0 edge_weight = int(x["weight"]) if 'weight' in x else 0 timestamp = int(x["time"]) if 'time' in x else 0 s.add_insert(source, destination, edge_type, weight=edge_weight, ts=timestamp, insert_strings=only_strings) # print "added edge", source, destination, edge_type, timestamp except Exception as e: print(traceback.format_exc()) pass # send immediately if the batch is now large current_batch_size = s.insertions_count + s.deletions_count + s.vertex_updates_count if current_batch_size > BATCH_THRESHOLD and BATCH_THRESHOLD > 0 or send_immediate: s.send_batch() print "Sending batch of size", current_batch_size, 'at', strftime( "%Y%m%d%H%M%S", gmtime()), "" except: print(traceback.format_exc()) r = json.dumps({"error": "Unable to parse object"}) return Response(response=r, status=400, mimetype="application/json") # end critical section finally: counter_lock.release() exec_time = time.time() - exec_time r = json.dumps({ "status": "success", "time": exec_time, "current_batch_size": current_batch_size }) return Response(response=r, status=201, mimetype="application/json")
from flask.ext.restplus import fields ## TODO: create enum type for possible statuses. ## TODO: document this build_process_list_response = { 'numberOfProcesses': fields.Integer(default=0), 'listOfProcesses': fields.List(fields.String) } ## TODO: document this build_basic_status_response = { 'token': fields.String, 'status': fields.String, 'context': fields.String, 'description': fields.String, 'imageName': fields.String, 'tag': fields.String } ## TODO: document this buildbase_basic_status_response = { 'name': fields.String, 'status': fields.String, 'description': fields.String } ## TODO: document this build_detailed_status_response = build_basic_status_response.copy() build_detailed_status_response['log'] = fields.String
app = Flask(__name__) app.wsgi_app = ProxyFix(app.wsgi_app) api = Api( app, version='1.0', title='TodoMVC API', description='A simple TodoMVC API', ) ns = api.namespace('todos', description='TODO operations') todo = api.model( 'Todo', { 'id': fields.Integer(readOnly=True, description='The task unique identifier'), 'task': fields.String(required=True, description='The task details') }) class TodoDAO(object): def __init__(self): self.counter = 0 self.todos = [] def get(self, id): for todo in self.todos: if todo['id'] == id: return todo api.abort(404, "Todo {} doesn't exist".format(id))
fields.String(required=True, default="diceMonit", description='The name given to the ES cluster'), 'nodeID': fields.String(required=True, default="esMaster", description='The name given to the ES node'), 'nodeMaster': fields.String( required=True, default="True", description='Set node as Master'), 'nodeData': fields.String(required=True, default="True", description='Allow node to store data'), 'shards': fields.Integer( required=True, default=5, description='Number of shards'), 'replicas': fields.Integer( required=True, default=1, description='Number of replicas'), 'networkHost': fields.String( required=True, default="0.0.0.0", description='Network host IP'), 'cacheSettings': fields.Nested(esCacheModel, description="Cache settings"), 'indexSettings': fields.Nested(esIndexSettingModel, description="Index settings") }) @agent.route('/v1/logs') class NodeLogs(Resource):
def test_defaults(self): field = fields.Integer() self.assertFalse(field.required) self.assertEqual(field.__schema__, {'type': 'integer'})
def test_simple_integer_field(self): field = fields.Integer() self.assertFalse(field.required) self.assertEqual(field.__schema__, {'type': 'integer'})
}) button_locations = api.model('ButtonLocations', { 'long': fields.Float(), 'lat': fields.Float() }) rules_field = api.model( 'RulesField', { 'code': fields.String(description='rule ID', required=True), 'description': fields.String(description='description of the parking rule', required=True), 'time_max_parking': fields.Integer(description='restriction on parking time (minutes)', required=True), 'agenda': fields.Nested( agenda_view, description= '''list of days when the restriction apply (1: monday, ..., 7: sunday) containing a list of time ranges when the restriction apply''', required=True), 'permit_no': fields.String( description='city parking permit number applicable for this slot', required=True), 'special_days': fields.String(required=True), 'restrict_types': fields.List(fields.String,
from flask.ext.restplus import fields, Resource from app import api, app RESOURCES_DIRECTORY = "resources/" ENGLISH_WORDS_FILE_NAME = "word_list.txt" cors = CORS(app, support_credentials=True) app.config['CORS_HEADERS'] = 'Content-Type' ns = api.namespace('4 Pic 1 Word', description='', path='/api/1.0') request_field = api.model('Enter the data', { 'character_set': fields.String(description='The Character Set that makes up the word', required=True), 'number_of_letter': fields.Integer(description='The number of letters in the word', required=True), }) def _get_possible_permutations(characters, number_of_letters): return [''.join(i) for i in permutations(characters, number_of_letters)] def _get_valid_english_words(possible_permutations): path = os.path.abspath(os.path.join(os.path.abspath(os.path.dirname(__file__)), RESOURCES_DIRECTORY + ENGLISH_WORDS_FILE_NAME)) try: with open(path) as word_file: english_words = set(word.strip().lower() for word in word_file) valid_english_words = [i for i in possible_permutations if i in english_words]