def migrate_models(): """ init elasticsearch models """ Group.init() MeetupZip.init() Token.init()
def update_all_group_events( self, group: Group, max_entries_per_page: int = 200) -> List[Event]: """ get all past events from meetup rest api & add it as child pages to the group Arguments: group {Group} -- Group to update Keyword Arguments: max_entries_per_page {int} -- How many events should be requestst at once on meetup (between 1 to 200) (default: {200}) Returns: List[Event] -- List[Event] every new Events wich wasn't already in elasticsearch """ # return [Event], init empty events: List[Event] = [] # fetch all events while True: group_events: List[Event] = self.update_group_events( group=group, max_entries=max_entries_per_page) group.add_events(events=group_events) group.save() # todo replace sleep with wait for save done sleep(1) events.extend(group_events) if len(group_events) == 0: break return events
def test_add_event_venue_to_list(): event: Event = Event( meetup_id=0, created=datetime.now(), time=datetime.now(), name="", link="", date_in_series_pattern=False, ) # check with event without venue venue_list_1: List[dict] = Group.add_event_venue_to_list(venue_list=[], event=event) assert len(venue_list_1) == 0 # add venue to event event.venue_name = "Café" event.venue_location = [52.520008, 13.404954] # check with any previous event venue_list_2: List[dict] = Group.add_event_venue_to_list( venue_list=venue_list_1, event=event) assert len(venue_list_2) == 1 # add again the same event venue_list_3: List[dict] = Group.add_event_venue_to_list( venue_list=venue_list_2, event=event) assert len(venue_list_3) == 1 # add a different event event.venue_location = [51.050407, 13.737262] venue_list_4: List[dict] = Group.add_event_venue_to_list( venue_list=venue_list_3, event=event) assert len(venue_list_4) == 2
def get_category_from_response(response: dict, group: Group) -> Group: """ parse json response and add the category to the given group Keyword arguments: response -- meetup api response in a dict Arguments: response {dict} -- meetup api response in a dict group {Group} -- The Group where the category will be added Returns: Group -- Given group with added category """ group.category_id = response["id"] if "name" in response: group.category_name = response["name"] if "shortname" in response: group.category_shortname = response["shortname"] if "sort_name" in response: group.category_sort_name = response["sort_name"] return group
def test_get_group(httpserver: HTTPServer, meetup_groups: dict, api_client: MeetupApiClient): # check existing group group_1: Group = api_client.get_group( group_urlname=meetup_groups["sandbox"]["urlname"]) assert isinstance(group_1, Group) assert group_1.meetup_id == meetup_groups["sandbox"]["meetup_id"] # check not existing group with pytest.raises(GroupDoesNotExistsOnMeetup): api_client.get_group( group_urlname=meetup_groups["not-exist"]["urlname"]) # create gone group object in elasticsearch group_2 = create_group(urlname=meetup_groups["gone"]["urlname"]) group_2.save() sleep(1) # check gone group with pytest.raises(GroupDoesNotExistsOnMeetup): api_client.get_group(group_urlname=meetup_groups["gone"]["urlname"]) sleep(1) # check if gone group was deleted with pytest.raises(GroupDoesNotExists): Group.get_group(urlname=meetup_groups["gone"]["urlname"]) # create gone group object in elasticsearch group_2 = create_group(urlname=meetup_groups["gone"]["urlname"]) group_2.save() sleep(1) # test for HttpNoXRateLimitHeader execption for _ in range(4): httpserver.expect_oneshot_request( "/HttpNoXRateLimitHeader").respond_with_data("OK") api_client.base_url = httpserver.url_for("/HttpNoXRateLimitHeader") with pytest.raises(MeetupConnectionError): api_client.get_group(group_urlname=meetup_groups["gone"]["urlname"]) # check if gone group was not deleted assert Group.get_group( urlname=meetup_groups["gone"]["urlname"]) is not None # test for HttpNoSuccess execption for _ in range(4): httpserver.expect_oneshot_request("/HttpNoSuccess") api_client.base_url = httpserver.url_for("") with pytest.raises(MeetupConnectionError): api_client.get_group(group_urlname=meetup_groups["gone"]["urlname"]) # check if gone group was not deleted assert Group.get_group( urlname=meetup_groups["gone"]["urlname"]) is not None
def test_update_groups(group_1: Group, meetup_groups: dict, app: Flask): runner: FlaskCliRunner = app.test_cli_runner() # init group to update group_1.urlname = meetup_groups["sandbox"]["urlname"] group_1.save() sleep(2) # update all groups result_1: Result = runner.invoke(update_groups) assert result_1.exit_code == 0 sleep(2) # check if group was updated group_2: Group = Group.get_group(urlname=group_1.urlname) assert len(group_2.events) > 0
def create_group(urlname: str, meetup_id: int = 0, name: str = "", lat: float = 0, lon: float = 0) -> Group: """ create group object Arguments: urlname {str} -- urlname for group object Keyword Arguments: meetup_id {int} -- meetup_id for group object (default: {0}) name {str} -- name for group object (default: {""}) Returns: Group -- new unsaved group object """ return Group( meetup_id=meetup_id, urlname=urlname, created=datetime.now(), description="", name=name, link="", location={ "lat": lat, "lon": lon }, members=0, status="", timezone="", visibility="", )
def create_events_to_group( search_query: str, valid_events: bool, group: Group, amount: int = 1, venue: bool = False, ) -> List[Event]: """ Create random test events and save them to a group Arguments: search_query {str} -- use query param for the search request valid_events {bool} -- should the groups searchable by the the query term group {Group} -- group to at the events Keyword Arguments: amount {int} -- how many events should be created (default: {1}) venue {bool} -- if venue should be added to eventa (default: {False}) Returns: List[Event] -- created & saved events """ created_events: List[Event] = [] for i in range(0, amount): event_name: str = random_string(search_query=search_query, valid=valid_events) event: Event = Event( meetup_id=event_name, time=datetime.now(), name=event_name, link="http://none", date_in_series_pattern=False, ) if venue: event.venue_name = event_name event.venue_location = {"lat": i + 1, "lon": i + 1} created_events.append(event) group.add_events(events=created_events) group.save() sleep(1) return created_events
def test_group_get_group(group_1: Group): # check when there is no group with pytest.raises(GroupDoesNotExists): Group.get_group(urlname=group_1.urlname) # save group group_1.save() sleep(1) # get group group_2: Group = Group.get_group(urlname=group_1.urlname) # check when there is a group assert isinstance(group_2, Group) assert group_2.urlname == group_1.urlname assert group_2.meetup_id == group_1.meetup_id assert group_2.created == group_1.created
def test_group_add_events(group_1: Group): # init group model group_1.save() # create 10 events events: List[Event] = [] for i in range(0, 10): event: Event = Event( meetup_id=str(i), created=datetime.now(), time=datetime.now(), name="", link="", date_in_series_pattern=False, ) events.append(event) # add events to group group_1.add_events(events) group_1.save() sleep(1) # check if events was added group_2: Group = Group.get_group(urlname=group_1.urlname) group_events: List[Event] = group_2.events assert len(group_events) == 10 for event in group_events: assert isinstance(group_events[i], Event) assert group_events[i].meetup_id == str(i)
def test_group_get_or_create_by_urlname(group_2: Group): # test with non exiting Group group_1: Group = Group.get_or_create_by_urlname( urlname=group_2.urlname, meetup_id=0, created=datetime.now(), description="", name="", link="", lat=0, lon=0, members=0, status="", timezone="", visibility="", ) sleep(1) # assert if request does not exist assert isinstance(group_1, Group) assert group_1.meetup_id == 0 # test with exiting Group group_2.save() sleep(1) # assert if request does exist group_3: Group = Group.get_or_create_by_urlname( urlname=group_2.urlname, meetup_id=0, created=datetime.now(), description="", name="", link="", lat=0, lon=0, members=0, status="", timezone="", visibility="", ) assert isinstance(group_3, Group) assert group_3.urlname == group_2.urlname assert group_3.meetup_id == group_2.meetup_id
def test_migrate_models_command(app: Flask): runner: FlaskCliRunner = app.test_cli_runner() # delete index delte_index() # check if index was deleted with pytest.raises(NotFoundError): Group.get_all_groups() with pytest.raises(NotFoundError): MeetupZip.get_all_zips() # migrate models result_1: Result = runner.invoke(migrate_models_command) assert result_1.exit_code == 0 sleep(2) # check if indexes was created assert isinstance(Group.get_all_groups(), List) assert isinstance(MeetupZip.get_all_zips(), List)
def update_groups(): """ update for all groups new events """ # get all groups groups: List[Group] = Group.get_all_groups() # init api client api_client: MeetupApiClient = MeetupApiClient() # update all groups for group in groups: api_client.update_all_group_events(group=group)
def test_get_venue_location_average(): # test with empty venue arry with pytest.raises(ValueError): Group.get_venue_location_average(venue_list=[]) # test average with a single event venue_list: List[dict] = [{"location": {"lat": 10, "lon": 10}}] venue_average_1: dict = Group.get_venue_location_average( venue_list=venue_list) assert venue_average_1["lat"] == 10 assert venue_average_1["lon"] == 10 # test with mmutiple venues venue_list.append({"location": {"lat": 20, "lon": 20}}) venue_list.append({"location": {"lat": 30, "lon": 30}}) venue_list.append({"location": {"lat": 40, "lon": 40}}) venue_list.append({"location": {"lat": 50, "lon": 50}}) venue_average_2: dict = Group.get_venue_location_average( venue_list=venue_list) assert venue_average_2["lat"] == 30 assert venue_average_2["lon"] == 30
def get_group_organizer_from_response(response: dict, group: Group) -> Group: """ parse json response and add organizer to the given group Keyword arguments: response -- meetup api response in a dict Arguments: response {dict} -- meetup api response in a dict group {Group} -- The Group where the organizer will be added Returns: Group -- Given group with added organizer """ group.organizer_id = response["id"] # add optional fields if "name" in response: group.organizer_name = response["name"] if "bio" in response: group.organizer_bio = response["bio"] return group
def get_group(self, group_urlname: str) -> Group: """ get or create a Group based on the group_urlname and fill / update the object from meetup rest api Arguments: group_urlname {str} -- Meetup group the urlname as string Raises: GroupDoesNotExistsOnMeetup: Group does not exists on Meetup.com MeetupConnectionError: Some network error to meetup.com Returns: Group -- Group based on the group_urlname """ try: response: dict = self.get("{}".format(group_urlname)) except (HttpNotAccessibleError, HttpNotFoundError): # delete group if exists Group.delete_if_exists(urlname=group_urlname) raise GroupDoesNotExistsOnMeetup( "{} group does not exists on meetup.com!".format( group_urlname)) except (HttpNoXRateLimitHeader): raise MeetupConnectionError( "Could not connect to meetup -> Rate Limits reached for {}!". format(group_urlname)) except (HttpNoSuccess): raise MeetupConnectionError( "Could not connect to meetup -> network problems for {}". format(group_urlname)) group: Group = get_group_from_response(response=response) group.save() return group
def test_get_groups_with_events(meetup_groups: dict, app: Flask): runner: FlaskCliRunner = app.test_cli_runner() # load all groups from JSON test file result_1: Result = runner.invoke( get_groups, ["/app/compose/local/flask/meetup_groups"] ) assert result_1.exit_code == 0 sleep(1) # load group group_1: Group = Group.get_group(urlname=meetup_groups["sandbox"]["urlname"]) # check if group has events assert len(group_1.events) > 0
def test_get_all_groups(group_1: Group, group_2: Group): # test with no group in es groups_1: List[Group] = Group.get_all_groups() assert len(groups_1) == 0 # init groups group_1.save() group_2.save() sleep(1) # test with 2 group in es groups_2: List[Group] = Group.get_all_groups() assert len(groups_2) == 2 assert isinstance(groups_2[0], Group)
def test_group_delete_if_exists(group_1: Group): # check when there is no group assert Group.delete_if_exists(urlname=group_1.urlname) is False # save group group_1.save() sleep(1) # delete group assert Group.delete_if_exists(urlname=group_1.urlname) is True sleep(1) # check if group is really deleted with pytest.raises(GroupDoesNotExists): Group.get_group(urlname=group_1.urlname)
def test_group_add_topic(group_1: Group): # init group model group_1.save() # add 10 topics & check if there was added for i in range(0, 10): topic: Topic = Topic(meetup_id=str(i), lang=str(i), name=str(i), urlkey=str(i)) group_1.add_topic(topic=topic) group_1.save() sleep(1) group_2: Group = Group.get_group(urlname=group_1.urlname) group_topics: List[Topic] = group_2.topics assert len(group_topics) == i + 1 assert isinstance(group_topics[i], Topic) assert group_topics[i].meetup_id == str(i)
def put(self) -> Dict[str, List[str]]: """ Get Suggestion for query term in Group name Returns: Dict[str, List[str]] -- a list to 5 suggestions """ args = self.parser.parse_args() # run suggest query search: Search = Group.search() search = search.suggest( "suggestion", args["query"], completion={"field": "name_suggest"}, ) response: Response = search.execute() # get suggestion suggestion: List[str] = [] for result in response.suggest.suggestion: for option in result.options: suggestion.append(option.text) return {"suggestions": suggestion}
def test_group_add_event(group_1: Group): # init group model group_1.save() # add 10 events & check if there was added for i in range(0, 10): event: Event = Event( meetup_id=str(i), created=datetime.now(), time=datetime.now(), name="", link="", date_in_series_pattern=False, ) group_1.add_event(event=event) group_1.save() sleep(1) group_2: Group = Group.get_group(urlname=group_1.urlname) group_events: List[Event] = group_2.events assert len(group_events) == i + 1 assert isinstance(group_events[i], Event) assert group_events[i].meetup_id == str(i)
def test_group_event_exists(group_1: Group, group_2: Group): # init group models group_1.save() group_2.save() # init event search_event: Event = Event( meetup_id=0, created=datetime.now(), time=datetime.now(), name="", link="", date_in_series_pattern=False, ) # test when event does not exists assert group_1.event_exists( event_meetup_id=search_event.meetup_id) is False # test with existing event group_1.add_event(search_event) group_1.save() assert group_1.event_exists(event_meetup_id=search_event.meetup_id) is True # test with saved event in wrong group assert group_2.event_exists( event_meetup_id=search_event.meetup_id) is False
def test_group_last_event_time(group_1: Group): events: dict = { "first": { "meetup_id": "first", "time": datetime(year=2000, month=1, day=1), }, "middle": { "meetup_id": "middle", "time": datetime(year=2010, month=1, day=1), }, "last": { "meetup_id": "last", "time": datetime(year=2020, month=1, day=1), }, } # init group models group_1.save() # test with no event assert group_1.last_event_time is None # test with one event event_first: Event = Event( meetup_id=events["first"]["meetup_id"], time=events["first"]["time"], name="", link="", date_in_series_pattern=False, ) group_1.add_event(event_first) group_1.save() assert group_1.last_event_time == events["first"]["time"] # test with 2 events event_last: Event = Event( meetup_id=events["last"]["meetup_id"], time=events["last"]["time"], name="", link="", date_in_series_pattern=False, ) group_1.add_event(event_last) group_1.save() assert group_1.last_event_time == events["last"]["time"] # test with 3 events event_middle: Event = Event( meetup_id=events["middle"]["meetup_id"], time=events["middle"]["time"], name="", link="", date_in_series_pattern=False, ) group_1.add_event(event_middle) group_1.save() assert group_1.last_event_time == events["last"]["time"]
def test_search_geo_distance(client: FlaskClient, group_1: Group): """ Test geo_distance filter Arguments: client {FlaskClient} -- client to access flask web ressource """ # init group with no location group_1.save() sleep(1) # test no location in groups, search for potsdam response_1: JSONResponse = client.put( url_for("meetupsearchapi"), data=generate_search_dict(query="*", geo_distance="100km", geo_lat=52.396149, geo_lon=13.058540), ) assert response_1.status_code == 200 assert len(response_1.json["results"]) == 0 assert response_1.json["hits"] == 0 assert isinstance(response_1, JSONResponse) # add berlin as location for group event_berlin: Event = Event( meetup_id="berlin", time=datetime.now(), name="berlin", link="http://none", date_in_series_pattern=False, venue_name="Café", venue_location={ "lat": 52.520008, "lon": 13.404954 }, ) group_1.add_event(event=event_berlin) group_1.save() sleep(1) # check if potsdam is in 100km from berlin center response_2: JSONResponse = client.put( url_for("meetupsearchapi"), data=generate_search_dict(query="*", geo_distance="100km", geo_lat=52.396149, geo_lon=13.058540), ) assert response_2.status_code == 200 assert len(response_2.json["results"]) == 1 assert response_2.json["hits"] == 1 assert isinstance(response_2, JSONResponse) # check if potsdam is in 1km from berlin center response_3: JSONResponse = client.put( url_for("meetupsearchapi"), data=generate_search_dict(query="*", geo_distance="0.5km", geo_lat=52.396149, geo_lon=13.058540), ) assert response_3.status_code == 200 assert len(response_3.json["results"]) == 0 assert response_3.json["hits"] == 0 assert isinstance(response_3, JSONResponse)
def put(self) -> dict: """ search for a group in Elasticsearch Returns: dict -- search results """ args = self.parser.parse_args() # init search search: Search = Group.search() search_query: dict = { "bool": { "should": [ {"query_string": {"query": args["query"], "fields": ["*"]}}, { "nested": { "path": "topics", "score_mode": "avg", "query": { "bool": { "must": [ { "query_string": { "query": args["query"], "fields": ["*"], } } ] } }, } }, { "nested": { "path": "events", "score_mode": "avg", "query": { "bool": { "must": [ { "query_string": { "query": args["query"], "fields": ["*"], } } ] } }, } }, ], "must": [], } } # set event time filter if args["event_time_gte"] or args["event_time_lte"]: range_query: dict = {} if args["event_time_gte"]: range_query["gte"] = args["event_time_gte"] if args["event_time_lte"]: range_query["lte"] = args["event_time_lte"] search_query["bool"]["must"].append( { "nested": { "path": "events", "score_mode": "avg", "query": { "bool": {"must": [{"range": {"events.time": range_query}}]} }, } } ) # set geo_distance filter if args["geo_distance"] and args["geo_lat"] and args["geo_lon"]: search_query["bool"]["must"].append( { "nested": { "path": "events", "score_mode": "avg", "query": { "bool": { "must": [ { "geo_distance": { "distance": args["geo_distance"], "events.venue_location": { "lat": args["geo_lat"], "lon": args["geo_lon"], }, } } ] } }, } } ) # pagination strat_entry: int = args["page"] * args["limit"] end_entry: int = strat_entry + args["limit"] search = search[strat_entry:end_entry] # sort if args["sort"]: search = Search().sort(args["sort"]) # execute search search = search.query(Q(search_query)) # set highlight score search.highlight_options(order="score") # load response from elasticsearch results: Response = search.execute() # get response found_groups: List[dict] = [] map_center_lat: float = 0 map_center_lon: float = 0 for group in results.hits: group_dict: dict = {} if isinstance(group, Hit): group_object = Group.get_group(urlname=group.to_dict()["urlname"]) group_dict = group_object.to_json_dict(load_events=args["load_events"]) else: group_dict = group.to_json_dict(load_events=args["load_events"]) if "venue_location_average" in group_dict: map_center_lat = ( map_center_lat + group_dict["venue_location_average"]["lat"] ) map_center_lon = ( map_center_lon + group_dict["venue_location_average"]["lon"] ) else: map_center_lat = map_center_lat + group_dict["location"]["lat"] map_center_lon = map_center_lon + group_dict["location"]["lon"] # add group dict to array found_groups.append( {**group_dict,} ) if len(found_groups) > 0: map_center_lat = map_center_lat / len(found_groups) map_center_lon = map_center_lon / len(found_groups) return { "results": found_groups, "hits": results.hits.total["value"], "map_center": {"lat": map_center_lat, "lon": map_center_lon}, }
def test_to_json_dict(group_1: Group): # add datetime element group_1.created = datetime.now() # test with no event assert isinstance(group_1.to_json_dict(load_events=True), dict) # check if an empty venue array was added assert len(group_1.to_json_dict(load_events=True)["venues"]) == 0 # check if venue_location_average is not set assert "venue_location_average" not in group_1.to_json_dict( load_events=True) # add event to group event: Event = Event( meetup_id=0, created=datetime.now(), time=datetime.now(), name="", link="", date_in_series_pattern=False, venue_name="Café", venue_location={ "lat": 52.520008, "lon": 13.404954 }, ) group_1.add_event(event=event) # test with event assert isinstance(group_1.to_json_dict(load_events=True), dict) # check if the venue array was added with loaded groups assert len(group_1.to_json_dict(load_events=True)["venues"]) == 1 # check if events are in dict assert len(group_1.to_json_dict(load_events=True)["events"]) == 1 # check if events not included in dict assert len(group_1.to_json_dict(load_events=False)["events"]) == 0 # check if the venue array was added without loaded groups assert len(group_1.to_json_dict(load_events=True)["venues"]) == 1 # check if venue_location_average is set assert (group_1.to_json_dict(load_events=True)["venue_location_average"] ["lat"] == event.venue_location["lat"]) assert (group_1.to_json_dict(load_events=True)["venue_location_average"] ["lon"] == event.venue_location["lon"])
def get_group_from_response(response: dict) -> Group: """ parse json response and return a Group Arguments: response {dict} -- meetup api response in a dict Returns: Group -- get or create Group based on urlname """ group = Group.get_or_create_by_urlname( urlname=response["urlname"], meetup_id=response["id"], created=datetime.fromtimestamp(response["created"] / 1000), description=response["description"], name=response["name"], link=response["link"], lat=response["lat"], lon=response["lon"], members=response["members"], status=response["status"], timezone=response["timezone"], visibility=response["visibility"], ) # add optional fields if "category" in response: group = get_category_from_response(response=response["category"], group=group) if "city" in response: group.city = response["city"] if "city_link" in response: group.city_link = response["city_link"] if "country" in response: group.country = response["country"] if "fee_options" in response: if "currencies" in response["fee_options"]: group.fee_options_currencies_code = response["fee_options"][ "currencies"]["code"] if "default" in response["fee_options"]["currencies"]: group.fee_options_currencies_default = response["fee_options"][ "currencies"]["default"] else: group.fee_options_currencies_default = False if "type" in response["fee_options"]: group.fee_options_type = response["fee_options"]["type"] if "join_mode" in response: group.join_mode = response["join_mode"] if "join_mode" in response: group.join_mode = response["join_mode"] if "localized_country_name" in response: group.localized_country_name = response["localized_country_name"] if "localized_location" in response: group.localized_location = response["localized_location"] if "member_limit" in response: group.member_limit = response["member_limit"] if "meta_category" in response: group = get_meta_category_from_response( response=response["meta_category"], group=group) if "nomination_acceptable" in response: group.nomination_acceptable = True else: group.nomination_acceptable = False if "organizer" in response: group = get_group_organizer_from_response( response=response["organizer"], group=group) if "short_link" in response: group.short_link = response["short_link"] if "state" in response: group.state = response["state"] if "status" in response: group.status = response["status"] if "topics" in response: group.topics.clear() for topic in response["topics"]: group.add_topic(topic=get_topic_from_response(response=topic)) if "untranslated_city" in response: group.untranslated_city = response["untranslated_city"] if "welcome_message" in response: group.welcome_message = response["welcome_message"] if "who" in response: group.who = response["who"] group.save() return group
def get_event_from_response(response: dict, group: Group) -> Event: """ parse json response and return an Event Arguments: response {dict} -- meetup api response in a dict group {Group} -- Group where the event should be added later Raises: EventAlreadyExists: Raise when a event with the same meetup_id already in the group exists Returns: Event -- New Event wich can be added to the group """ # if event already exists, raise try: if group.event_exists(event_meetup_id=response["id"]): raise EventAlreadyExists("Event {} already exists on {}!".format( response["id"], group.name)) except KeyError: raise InvalidResponse("No Event in Response!") date_in_series_pattern: bool = False if "date_in_series_pattern" in response: date_in_series_pattern = response["date_in_series_pattern"] event: Event = Event( meetup_id=response["id"], time=datetime.fromtimestamp(response["time"] / 1000), name=response["name"], link=response["link"], date_in_series_pattern=date_in_series_pattern, ) # add optional fields if "attendance_count" in response: event.attendance_count = response["attendance_count"] if "attendance_sample" in response: event.attendance_sample = response["attendance_sample"] if "attendee_sample" in response: event.attendee_sample = response["attendee_sample"] if "created" in response: event.created = datetime.fromtimestamp(response["created"] / 1000) if "description" in response: event.description = response["description"] if "duration" in response: event.duration = response["duration"] if "fee" in response: event.fee_accepts = response["fee"]["accepts"] event.fee_amount = response["fee"]["amount"] event.fee_currency = response["fee"]["currency"] event.fee_description = response["fee"]["description"] event.fee_label = response["fee"]["label"] if "how_to_find_us" in response: event.how_to_find_us = response["how_to_find_us"] if "status" in response: event.status = response["status"] if "utc_offset" in response: event.utc_offset = response["utc_offset"] / 1000 if "updated" in response: event.updated = datetime.fromtimestamp(response["updated"] / 1000) if "venue" in response: event = get_venue_from_response(response=response["venue"], event=event) if "venue_visibility" in response: event.venue_visibility = response["venue_visibility"] if "visibility" in response: event.visibility = response["visibility"] return event