We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Check if datetime fields exists in Event API payload before using them
Currently when string datetime's are converted to python datetime in Event API, then the keys are not being checked for existence. So if an "optional" field is missing from payload, it results in `KeyError`. 

Fixing this issue should also fix https://github.com/loklak/loklak_server/issues/642


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `open_event/api/events.py`
Content:
```
1 from flask.ext.restplus import Resource, Namespace, reqparse
2 from flask import g
3 
4 from open_event.models.event import Event as EventModel
5 from open_event.models.social_link import SocialLink as SocialLinkModel
6 from open_event.models.users_events_roles import UsersEventsRoles
7 from open_event.models.role import Role
8 from open_event.models.user import ORGANIZER
9 from open_event.helpers.data import save_to_db, update_version, record_activity
10 
11 from .helpers.helpers import get_paginated_list, requires_auth, parse_args
12 from .helpers.utils import PAGINATED_MODEL, PaginatedResourceBase, \
13     PAGE_PARAMS, POST_RESPONSES, PUT_RESPONSES, BaseDAO, ServiceDAO
14 from .helpers import custom_fields as fields
15 from helpers.special_fields import EventTypeField, EventTopicField, \
16     EventPrivacyField, EventSubTopicField
17 
18 api = Namespace('events', description='Events')
19 
20 EVENT_CREATOR = api.model('EventCreator', {
21     'id': fields.Integer(),
22     'email': fields.Email()
23 })
24 
25 SOCIAL_LINK = api.model('SocialLink', {
26     'id': fields.Integer(),
27     'name': fields.String(),
28     'link': fields.String()
29 })
30 
31 SOCIAL_LINK_POST = api.clone('SocialLinkPost', SOCIAL_LINK)
32 del SOCIAL_LINK_POST['id']
33 
34 EVENT = api.model('Event', {
35     'id': fields.Integer(required=True),
36     'name': fields.String(required=True),
37     'email': fields.Email(),
38     'logo': fields.Upload(),
39     'start_time': fields.DateTime(required=True),
40     'end_time': fields.DateTime(required=True),
41     'timezone': fields.String(),
42     'latitude': fields.Float(),
43     'longitude': fields.Float(),
44     'event_url': fields.Uri(),
45     'background_url': fields.Upload(),
46     'description': fields.String(),
47     'location_name': fields.String(),
48     'organizer_name': fields.String(),
49     'organizer_description': fields.String(),
50     'state': fields.String(),
51     'closing_datetime': fields.DateTime(),
52     'type': EventTypeField(),
53     'topic': EventTopicField(),
54     'sub_topic': EventSubTopicField(),
55     'privacy': EventPrivacyField(),
56     'ticket_url': fields.Uri(),
57     'creator': fields.Nested(EVENT_CREATOR, allow_null=True),
58     'schedule_published_on': fields.DateTime(),
59     'code_of_conduct': fields.String(),
60     'social_links': fields.List(fields.Nested(SOCIAL_LINK), attribute='social_link')
61 })
62 
63 EVENT_PAGINATED = api.clone('EventPaginated', PAGINATED_MODEL, {
64     'results': fields.List(fields.Nested(EVENT))
65 })
66 
67 EVENT_POST = api.clone('EventPost', EVENT)
68 del EVENT_POST['id']
69 del EVENT_POST['creator']
70 del EVENT_POST['social_links']
71 
72 
73 
74 # ###################
75 # Data Access Objects
76 # ###################
77 
78 
79 class SocialLinkDAO(ServiceDAO):
80     """
81     Social Link DAO
82     """
83     pass
84 
85 
86 class EventDAO(BaseDAO):
87     """
88     Event DAO
89     """
90 
91     def fix_payload(self, data):
92         """
93         Fixes the payload data.
94         Here converts string time from datetime obj
95         """
96         data['start_time'] = EVENT_POST['start_time'].from_str(data['start_time'])
97         data['end_time'] = EVENT_POST['end_time'].from_str(data['end_time'])
98         data['closing_datetime'] = EVENT_POST['closing_datetime'].from_str(
99             data['closing_datetime'])
100         data['schedule_published_on'] = EVENT_POST['schedule_published_on'].from_str(
101             data['schedule_published_on'])
102         return data
103 
104     def create(self, data, url):
105         data = self.validate(data)
106         payload = self.fix_payload(data)
107         new_event = self.model(**payload)
108         new_event.creator = g.user
109         save_to_db(new_event, "Event saved")
110         # set organizer
111         role = Role.query.filter_by(name=ORGANIZER).first()
112         uer = UsersEventsRoles(g.user, new_event, role)
113         save_to_db(uer, 'UER saved')
114         update_version(
115             event_id=new_event.id,
116             is_created=True,
117             column_to_increment="event_ver"
118         )
119         # Return created resource with a 201 status code and its Location
120         # (url) in the header.
121         resource_location = url + '/' + str(new_event.id)
122         return self.get(new_event.id), 201, {'Location': resource_location}
123 
124     def update(self, event_id, data):
125         data = self.validate(data)
126         payload = self.fix_payload(data)
127         return BaseDAO.update(self, event_id, payload, validate=False)
128 
129 
130 LinkDAO = SocialLinkDAO(SocialLinkModel, SOCIAL_LINK_POST)
131 DAO = EventDAO(EventModel, EVENT_POST)
132 
133 # DEFINE PARAMS
134 
135 EVENT_PARAMS = {
136     'location': {
137         'type': str
138     },
139     'contains': {
140         'description': 'Contains the string in name and description',
141         'type': str
142     },
143     'state': {
144         'type': str
145     },
146     'privacy': {
147         'type': str
148     },
149     'type': {
150         'type': str
151     },
152     'topic': {
153         'type': str
154     },
155     'sub_topic': {
156         'type': str
157     },
158     'start_time_gt': {},
159     'start_time_lt': {},
160     'end_time_gt': {},
161     'end_time_lt': {},
162     'time_period': {
163         'type': str
164     }
165 }
166 
167 
168 # DEFINE RESOURCES
169 
170 
171 class EventResource():
172     """
173     Event Resource Base class
174     """
175     event_parser = reqparse.RequestParser()
176     event_parser.add_argument('location', type=str, dest='__event_location')
177     event_parser.add_argument('contains', type=str, dest='__event_contains')
178     event_parser.add_argument('state', type=str)
179     event_parser.add_argument('privacy', type=str)
180     event_parser.add_argument('type', type=str)
181     event_parser.add_argument('topic', type=str)
182     event_parser.add_argument('sub_topic', type=str)
183     event_parser.add_argument('start_time_gt', dest='__event_start_time_gt')
184     event_parser.add_argument('start_time_lt', dest='__event_start_time_lt')
185     event_parser.add_argument('end_time_gt', dest='__event_end_time_gt')
186     event_parser.add_argument('end_time_lt', dest='__event_end_time_lt')
187     event_parser.add_argument('time_period', type=str, dest='__event_time_period')
188 
189 
190 @api.route('/<int:event_id>')
191 @api.param('event_id')
192 @api.response(404, 'Event not found')
193 class Event(Resource):
194     @api.doc('get_event')
195     @api.marshal_with(EVENT)
196     def get(self, event_id):
197         """Fetch an event given its id"""
198         return DAO.get(event_id)
199 
200     @requires_auth
201     @api.doc('delete_event')
202     @api.marshal_with(EVENT)
203     def delete(self, event_id):
204         """Delete an event given its id"""
205         event = DAO.delete(event_id)
206         record_activity('delete_event', event_id=event_id)
207         return event
208 
209     @requires_auth
210     @api.doc('update_event', responses=PUT_RESPONSES)
211     @api.marshal_with(EVENT)
212     @api.expect(EVENT_POST)
213     def put(self, event_id):
214         """Update an event given its id"""
215         event = DAO.update(event_id, self.api.payload)
216         record_activity('update_event', event_id=event_id)
217         return event
218 
219 
220 @api.route('')
221 class EventList(Resource, EventResource):
222     @api.doc('list_events', params=EVENT_PARAMS)
223     @api.marshal_list_with(EVENT)
224     def get(self):
225         """List all events"""
226         return DAO.list(**parse_args(self.event_parser))
227 
228     @requires_auth
229     @api.doc('create_event', responses=POST_RESPONSES)
230     @api.marshal_with(EVENT)
231     @api.expect(EVENT_POST)
232     def post(self):
233         """Create an event"""
234         item = DAO.create(self.api.payload, self.api.url_for(self))
235         record_activity('create_event', event_id=item[0].id)
236         return item
237 
238 
239 @api.route('/page')
240 class EventListPaginated(Resource, PaginatedResourceBase, EventResource):
241     @api.doc('list_events_paginated', params=PAGE_PARAMS)
242     @api.doc(params=EVENT_PARAMS)
243     @api.marshal_with(EVENT_PAGINATED)
244     def get(self):
245         """List events in a paginated manner"""
246         args = self.parser.parse_args()
247         return get_paginated_list(
248             EventModel, args=args,
249             **parse_args(self.event_parser)
250         )
251 
252 
253 @api.route('/<int:event_id>/links')
254 @api.param('event_id')
255 class SocialLinkList(Resource):
256     @api.doc('list_social_links')
257     @api.marshal_list_with(SOCIAL_LINK)
258     def get(self, event_id):
259         """List all social links"""
260         return LinkDAO.list(event_id)
261 
262     @requires_auth
263     @api.doc('create_social_link', responses=POST_RESPONSES)
264     @api.marshal_with(SOCIAL_LINK_POST)
265     @api.expect(SOCIAL_LINK_POST)
266     def post(self, event_id):
267         """Create a social link"""
268         return LinkDAO.create(
269             event_id,
270             self.api.payload,
271             self.api.url_for(self, event_id=event_id)
272         )
273 
274 
275 @api.route('/<int:event_id>/links/<int:link_id>')
276 class SocialLink(Resource):
277     @requires_auth
278     @api.doc('delete_social_link')
279     @api.marshal_with(SOCIAL_LINK)
280     def delete(self, event_id, link_id):
281         """Delete a social link given its id"""
282         return LinkDAO.delete(event_id, link_id)
283 
284     @requires_auth
285     @api.doc('update_social_link', responses=PUT_RESPONSES)
286     @api.marshal_with(SOCIAL_LINK_POST)
287     @api.expect(SOCIAL_LINK_POST)
288     def put(self, event_id, link_id):
289         """Update a social link given its id"""
290         return LinkDAO.update(event_id, link_id, self.api.payload)
291
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/open_event/api/events.py b/open_event/api/events.py
--- a/open_event/api/events.py
+++ b/open_event/api/events.py
@@ -70,7 +70,6 @@
 del EVENT_POST['social_links']
 
 
-
 # ###################
 # Data Access Objects
 # ###################
@@ -93,12 +92,12 @@
         Fixes the payload data.
         Here converts string time from datetime obj
         """
-        data['start_time'] = EVENT_POST['start_time'].from_str(data['start_time'])
-        data['end_time'] = EVENT_POST['end_time'].from_str(data['end_time'])
-        data['closing_datetime'] = EVENT_POST['closing_datetime'].from_str(
-            data['closing_datetime'])
-        data['schedule_published_on'] = EVENT_POST['schedule_published_on'].from_str(
-            data['schedule_published_on'])
+        datetime_fields = [
+            'start_time', 'end_time', 'closing_datetime',
+            'schedule_published_on'
+        ]
+        for i in datetime_fields:
+            data[i] = EVENT_POST[i].from_str(data.get(i))
         return data
 
     def create(self, data, url):
@@ -133,35 +132,20 @@
 # DEFINE PARAMS
 
 EVENT_PARAMS = {
-    'location': {
-        'type': str
-    },
+    'location': {},
     'contains': {
-        'description': 'Contains the string in name and description',
-        'type': str
-    },
-    'state': {
-        'type': str
-    },
-    'privacy': {
-        'type': str
-    },
-    'type': {
-        'type': str
-    },
-    'topic': {
-        'type': str
-    },
-    'sub_topic': {
-        'type': str
+        'description': 'Contains the string in name and description'
     },
+    'state': {},
+    'privacy': {},
+    'type': {},
+    'topic': {},
+    'sub_topic': {},
     'start_time_gt': {},
     'start_time_lt': {},
     'end_time_gt': {},
     'end_time_lt': {},
-    'time_period': {
-        'type': str
-    }
+    'time_period': {}
 }

{"golden_diff": "diff --git a/open_event/api/events.py b/open_event/api/events.py\n--- a/open_event/api/events.py\n+++ b/open_event/api/events.py\n@@ -70,7 +70,6 @@\n del EVENT_POST['social_links']\n \n \n-\n # ###################\n # Data Access Objects\n # ###################\n@@ -93,12 +92,12 @@\n         Fixes the payload data.\n         Here converts string time from datetime obj\n         \"\"\"\n-        data['start_time'] = EVENT_POST['start_time'].from_str(data['start_time'])\n-        data['end_time'] = EVENT_POST['end_time'].from_str(data['end_time'])\n-        data['closing_datetime'] = EVENT_POST['closing_datetime'].from_str(\n-            data['closing_datetime'])\n-        data['schedule_published_on'] = EVENT_POST['schedule_published_on'].from_str(\n-            data['schedule_published_on'])\n+        datetime_fields = [\n+            'start_time', 'end_time', 'closing_datetime',\n+            'schedule_published_on'\n+        ]\n+        for i in datetime_fields:\n+            data[i] = EVENT_POST[i].from_str(data.get(i))\n         return data\n \n     def create(self, data, url):\n@@ -133,35 +132,20 @@\n # DEFINE PARAMS\n \n EVENT_PARAMS = {\n-    'location': {\n-        'type': str\n-    },\n+    'location': {},\n     'contains': {\n-        'description': 'Contains the string in name and description',\n-        'type': str\n-    },\n-    'state': {\n-        'type': str\n-    },\n-    'privacy': {\n-        'type': str\n-    },\n-    'type': {\n-        'type': str\n-    },\n-    'topic': {\n-        'type': str\n-    },\n-    'sub_topic': {\n-        'type': str\n+        'description': 'Contains the string in name and description'\n     },\n+    'state': {},\n+    'privacy': {},\n+    'type': {},\n+    'topic': {},\n+    'sub_topic': {},\n     'start_time_gt': {},\n     'start_time_lt': {},\n     'end_time_gt': {},\n     'end_time_lt': {},\n-    'time_period': {\n-        'type': str\n-    }\n+    'time_period': {}\n }\n", "issue": "Check if datetime fields exists in Event API payload before using them\nCurrently when string datetime's are converted to python datetime in Event API, then the keys are not being checked for existence. So if an \"optional\" field is missing from payload, it results in `KeyError`. \n\nFixing this issue should also fix https://github.com/loklak/loklak_server/issues/642\n\n", "before_files": [{"content": "from flask.ext.restplus import Resource, Namespace, reqparse\nfrom flask import g\n\nfrom open_event.models.event import Event as EventModel\nfrom open_event.models.social_link import SocialLink as SocialLinkModel\nfrom open_event.models.users_events_roles import UsersEventsRoles\nfrom open_event.models.role import Role\nfrom open_event.models.user import ORGANIZER\nfrom open_event.helpers.data import save_to_db, update_version, record_activity\n\nfrom .helpers.helpers import get_paginated_list, requires_auth, parse_args\nfrom .helpers.utils import PAGINATED_MODEL, PaginatedResourceBase, \\\n    PAGE_PARAMS, POST_RESPONSES, PUT_RESPONSES, BaseDAO, ServiceDAO\nfrom .helpers import custom_fields as fields\nfrom helpers.special_fields import EventTypeField, EventTopicField, \\\n    EventPrivacyField, EventSubTopicField\n\napi = Namespace('events', description='Events')\n\nEVENT_CREATOR = api.model('EventCreator', {\n    'id': fields.Integer(),\n    'email': fields.Email()\n})\n\nSOCIAL_LINK = api.model('SocialLink', {\n    'id': fields.Integer(),\n    'name': fields.String(),\n    'link': fields.String()\n})\n\nSOCIAL_LINK_POST = api.clone('SocialLinkPost', SOCIAL_LINK)\ndel SOCIAL_LINK_POST['id']\n\nEVENT = api.model('Event', {\n    'id': fields.Integer(required=True),\n    'name': fields.String(required=True),\n    'email': fields.Email(),\n    'logo': fields.Upload(),\n    'start_time': fields.DateTime(required=True),\n    'end_time': fields.DateTime(required=True),\n    'timezone': fields.String(),\n    'latitude': fields.Float(),\n    'longitude': fields.Float(),\n    'event_url': fields.Uri(),\n    'background_url': fields.Upload(),\n    'description': fields.String(),\n    'location_name': fields.String(),\n    'organizer_name': fields.String(),\n    'organizer_description': fields.String(),\n    'state': fields.String(),\n    'closing_datetime': fields.DateTime(),\n    'type': EventTypeField(),\n    'topic': EventTopicField(),\n    'sub_topic': EventSubTopicField(),\n    'privacy': EventPrivacyField(),\n    'ticket_url': fields.Uri(),\n    'creator': fields.Nested(EVENT_CREATOR, allow_null=True),\n    'schedule_published_on': fields.DateTime(),\n    'code_of_conduct': fields.String(),\n    'social_links': fields.List(fields.Nested(SOCIAL_LINK), attribute='social_link')\n})\n\nEVENT_PAGINATED = api.clone('EventPaginated', PAGINATED_MODEL, {\n    'results': fields.List(fields.Nested(EVENT))\n})\n\nEVENT_POST = api.clone('EventPost', EVENT)\ndel EVENT_POST['id']\ndel EVENT_POST['creator']\ndel EVENT_POST['social_links']\n\n\n\n# ###################\n# Data Access Objects\n# ###################\n\n\nclass SocialLinkDAO(ServiceDAO):\n    \"\"\"\n    Social Link DAO\n    \"\"\"\n    pass\n\n\nclass EventDAO(BaseDAO):\n    \"\"\"\n    Event DAO\n    \"\"\"\n\n    def fix_payload(self, data):\n        \"\"\"\n        Fixes the payload data.\n        Here converts string time from datetime obj\n        \"\"\"\n        data['start_time'] = EVENT_POST['start_time'].from_str(data['start_time'])\n        data['end_time'] = EVENT_POST['end_time'].from_str(data['end_time'])\n        data['closing_datetime'] = EVENT_POST['closing_datetime'].from_str(\n            data['closing_datetime'])\n        data['schedule_published_on'] = EVENT_POST['schedule_published_on'].from_str(\n            data['schedule_published_on'])\n        return data\n\n    def create(self, data, url):\n        data = self.validate(data)\n        payload = self.fix_payload(data)\n        new_event = self.model(**payload)\n        new_event.creator = g.user\n        save_to_db(new_event, \"Event saved\")\n        # set organizer\n        role = Role.query.filter_by(name=ORGANIZER).first()\n        uer = UsersEventsRoles(g.user, new_event, role)\n        save_to_db(uer, 'UER saved')\n        update_version(\n            event_id=new_event.id,\n            is_created=True,\n            column_to_increment=\"event_ver\"\n        )\n        # Return created resource with a 201 status code and its Location\n        # (url) in the header.\n        resource_location = url + '/' + str(new_event.id)\n        return self.get(new_event.id), 201, {'Location': resource_location}\n\n    def update(self, event_id, data):\n        data = self.validate(data)\n        payload = self.fix_payload(data)\n        return BaseDAO.update(self, event_id, payload, validate=False)\n\n\nLinkDAO = SocialLinkDAO(SocialLinkModel, SOCIAL_LINK_POST)\nDAO = EventDAO(EventModel, EVENT_POST)\n\n# DEFINE PARAMS\n\nEVENT_PARAMS = {\n    'location': {\n        'type': str\n    },\n    'contains': {\n        'description': 'Contains the string in name and description',\n        'type': str\n    },\n    'state': {\n        'type': str\n    },\n    'privacy': {\n        'type': str\n    },\n    'type': {\n        'type': str\n    },\n    'topic': {\n        'type': str\n    },\n    'sub_topic': {\n        'type': str\n    },\n    'start_time_gt': {},\n    'start_time_lt': {},\n    'end_time_gt': {},\n    'end_time_lt': {},\n    'time_period': {\n        'type': str\n    }\n}\n\n\n# DEFINE RESOURCES\n\n\nclass EventResource():\n    \"\"\"\n    Event Resource Base class\n    \"\"\"\n    event_parser = reqparse.RequestParser()\n    event_parser.add_argument('location', type=str, dest='__event_location')\n    event_parser.add_argument('contains', type=str, dest='__event_contains')\n    event_parser.add_argument('state', type=str)\n    event_parser.add_argument('privacy', type=str)\n    event_parser.add_argument('type', type=str)\n    event_parser.add_argument('topic', type=str)\n    event_parser.add_argument('sub_topic', type=str)\n    event_parser.add_argument('start_time_gt', dest='__event_start_time_gt')\n    event_parser.add_argument('start_time_lt', dest='__event_start_time_lt')\n    event_parser.add_argument('end_time_gt', dest='__event_end_time_gt')\n    event_parser.add_argument('end_time_lt', dest='__event_end_time_lt')\n    event_parser.add_argument('time_period', type=str, dest='__event_time_period')\n\n\n@api.route('/<int:event_id>')\n@api.param('event_id')\n@api.response(404, 'Event not found')\nclass Event(Resource):\n    @api.doc('get_event')\n    @api.marshal_with(EVENT)\n    def get(self, event_id):\n        \"\"\"Fetch an event given its id\"\"\"\n        return DAO.get(event_id)\n\n    @requires_auth\n    @api.doc('delete_event')\n    @api.marshal_with(EVENT)\n    def delete(self, event_id):\n        \"\"\"Delete an event given its id\"\"\"\n        event = DAO.delete(event_id)\n        record_activity('delete_event', event_id=event_id)\n        return event\n\n    @requires_auth\n    @api.doc('update_event', responses=PUT_RESPONSES)\n    @api.marshal_with(EVENT)\n    @api.expect(EVENT_POST)\n    def put(self, event_id):\n        \"\"\"Update an event given its id\"\"\"\n        event = DAO.update(event_id, self.api.payload)\n        record_activity('update_event', event_id=event_id)\n        return event\n\n\n@api.route('')\nclass EventList(Resource, EventResource):\n    @api.doc('list_events', params=EVENT_PARAMS)\n    @api.marshal_list_with(EVENT)\n    def get(self):\n        \"\"\"List all events\"\"\"\n        return DAO.list(**parse_args(self.event_parser))\n\n    @requires_auth\n    @api.doc('create_event', responses=POST_RESPONSES)\n    @api.marshal_with(EVENT)\n    @api.expect(EVENT_POST)\n    def post(self):\n        \"\"\"Create an event\"\"\"\n        item = DAO.create(self.api.payload, self.api.url_for(self))\n        record_activity('create_event', event_id=item[0].id)\n        return item\n\n\n@api.route('/page')\nclass EventListPaginated(Resource, PaginatedResourceBase, EventResource):\n    @api.doc('list_events_paginated', params=PAGE_PARAMS)\n    @api.doc(params=EVENT_PARAMS)\n    @api.marshal_with(EVENT_PAGINATED)\n    def get(self):\n        \"\"\"List events in a paginated manner\"\"\"\n        args = self.parser.parse_args()\n        return get_paginated_list(\n            EventModel, args=args,\n            **parse_args(self.event_parser)\n        )\n\n\n@api.route('/<int:event_id>/links')\n@api.param('event_id')\nclass SocialLinkList(Resource):\n    @api.doc('list_social_links')\n    @api.marshal_list_with(SOCIAL_LINK)\n    def get(self, event_id):\n        \"\"\"List all social links\"\"\"\n        return LinkDAO.list(event_id)\n\n    @requires_auth\n    @api.doc('create_social_link', responses=POST_RESPONSES)\n    @api.marshal_with(SOCIAL_LINK_POST)\n    @api.expect(SOCIAL_LINK_POST)\n    def post(self, event_id):\n        \"\"\"Create a social link\"\"\"\n        return LinkDAO.create(\n            event_id,\n            self.api.payload,\n            self.api.url_for(self, event_id=event_id)\n        )\n\n\n@api.route('/<int:event_id>/links/<int:link_id>')\nclass SocialLink(Resource):\n    @requires_auth\n    @api.doc('delete_social_link')\n    @api.marshal_with(SOCIAL_LINK)\n    def delete(self, event_id, link_id):\n        \"\"\"Delete a social link given its id\"\"\"\n        return LinkDAO.delete(event_id, link_id)\n\n    @requires_auth\n    @api.doc('update_social_link', responses=PUT_RESPONSES)\n    @api.marshal_with(SOCIAL_LINK_POST)\n    @api.expect(SOCIAL_LINK_POST)\n    def put(self, event_id, link_id):\n        \"\"\"Update a social link given its id\"\"\"\n        return LinkDAO.update(event_id, link_id, self.api.payload)\n", "path": "open_event/api/events.py"}], "after_files": [{"content": "from flask.ext.restplus import Resource, Namespace, reqparse\nfrom flask import g\n\nfrom open_event.models.event import Event as EventModel\nfrom open_event.models.social_link import SocialLink as SocialLinkModel\nfrom open_event.models.users_events_roles import UsersEventsRoles\nfrom open_event.models.role import Role\nfrom open_event.models.user import ORGANIZER\nfrom open_event.helpers.data import save_to_db, update_version, record_activity\n\nfrom .helpers.helpers import get_paginated_list, requires_auth, parse_args\nfrom .helpers.utils import PAGINATED_MODEL, PaginatedResourceBase, \\\n    PAGE_PARAMS, POST_RESPONSES, PUT_RESPONSES, BaseDAO, ServiceDAO\nfrom .helpers import custom_fields as fields\nfrom helpers.special_fields import EventTypeField, EventTopicField, \\\n    EventPrivacyField, EventSubTopicField\n\napi = Namespace('events', description='Events')\n\nEVENT_CREATOR = api.model('EventCreator', {\n    'id': fields.Integer(),\n    'email': fields.Email()\n})\n\nSOCIAL_LINK = api.model('SocialLink', {\n    'id': fields.Integer(),\n    'name': fields.String(),\n    'link': fields.String()\n})\n\nSOCIAL_LINK_POST = api.clone('SocialLinkPost', SOCIAL_LINK)\ndel SOCIAL_LINK_POST['id']\n\nEVENT = api.model('Event', {\n    'id': fields.Integer(required=True),\n    'name': fields.String(required=True),\n    'email': fields.Email(),\n    'logo': fields.Upload(),\n    'start_time': fields.DateTime(required=True),\n    'end_time': fields.DateTime(required=True),\n    'timezone': fields.String(),\n    'latitude': fields.Float(),\n    'longitude': fields.Float(),\n    'event_url': fields.Uri(),\n    'background_url': fields.Upload(),\n    'description': fields.String(),\n    'location_name': fields.String(),\n    'organizer_name': fields.String(),\n    'organizer_description': fields.String(),\n    'state': fields.String(),\n    'closing_datetime': fields.DateTime(),\n    'type': EventTypeField(),\n    'topic': EventTopicField(),\n    'sub_topic': EventSubTopicField(),\n    'privacy': EventPrivacyField(),\n    'ticket_url': fields.Uri(),\n    'creator': fields.Nested(EVENT_CREATOR, allow_null=True),\n    'schedule_published_on': fields.DateTime(),\n    'code_of_conduct': fields.String(),\n    'social_links': fields.List(fields.Nested(SOCIAL_LINK), attribute='social_link')\n})\n\nEVENT_PAGINATED = api.clone('EventPaginated', PAGINATED_MODEL, {\n    'results': fields.List(fields.Nested(EVENT))\n})\n\nEVENT_POST = api.clone('EventPost', EVENT)\ndel EVENT_POST['id']\ndel EVENT_POST['creator']\ndel EVENT_POST['social_links']\n\n\n# ###################\n# Data Access Objects\n# ###################\n\n\nclass SocialLinkDAO(ServiceDAO):\n    \"\"\"\n    Social Link DAO\n    \"\"\"\n    pass\n\n\nclass EventDAO(BaseDAO):\n    \"\"\"\n    Event DAO\n    \"\"\"\n\n    def fix_payload(self, data):\n        \"\"\"\n        Fixes the payload data.\n        Here converts string time from datetime obj\n        \"\"\"\n        datetime_fields = [\n            'start_time', 'end_time', 'closing_datetime',\n            'schedule_published_on'\n        ]\n        for i in datetime_fields:\n            data[i] = EVENT_POST[i].from_str(data.get(i))\n        return data\n\n    def create(self, data, url):\n        data = self.validate(data)\n        payload = self.fix_payload(data)\n        new_event = self.model(**payload)\n        new_event.creator = g.user\n        save_to_db(new_event, \"Event saved\")\n        # set organizer\n        role = Role.query.filter_by(name=ORGANIZER).first()\n        uer = UsersEventsRoles(g.user, new_event, role)\n        save_to_db(uer, 'UER saved')\n        update_version(\n            event_id=new_event.id,\n            is_created=True,\n            column_to_increment=\"event_ver\"\n        )\n        # Return created resource with a 201 status code and its Location\n        # (url) in the header.\n        resource_location = url + '/' + str(new_event.id)\n        return self.get(new_event.id), 201, {'Location': resource_location}\n\n    def update(self, event_id, data):\n        data = self.validate(data)\n        payload = self.fix_payload(data)\n        return BaseDAO.update(self, event_id, payload, validate=False)\n\n\nLinkDAO = SocialLinkDAO(SocialLinkModel, SOCIAL_LINK_POST)\nDAO = EventDAO(EventModel, EVENT_POST)\n\n# DEFINE PARAMS\n\nEVENT_PARAMS = {\n    'location': {},\n    'contains': {\n        'description': 'Contains the string in name and description'\n    },\n    'state': {},\n    'privacy': {},\n    'type': {},\n    'topic': {},\n    'sub_topic': {},\n    'start_time_gt': {},\n    'start_time_lt': {},\n    'end_time_gt': {},\n    'end_time_lt': {},\n    'time_period': {}\n}\n\n\n# DEFINE RESOURCES\n\n\nclass EventResource():\n    \"\"\"\n    Event Resource Base class\n    \"\"\"\n    event_parser = reqparse.RequestParser()\n    event_parser.add_argument('location', type=str, dest='__event_location')\n    event_parser.add_argument('contains', type=str, dest='__event_contains')\n    event_parser.add_argument('state', type=str)\n    event_parser.add_argument('privacy', type=str)\n    event_parser.add_argument('type', type=str)\n    event_parser.add_argument('topic', type=str)\n    event_parser.add_argument('sub_topic', type=str)\n    event_parser.add_argument('start_time_gt', dest='__event_start_time_gt')\n    event_parser.add_argument('start_time_lt', dest='__event_start_time_lt')\n    event_parser.add_argument('end_time_gt', dest='__event_end_time_gt')\n    event_parser.add_argument('end_time_lt', dest='__event_end_time_lt')\n    event_parser.add_argument('time_period', type=str, dest='__event_time_period')\n\n\n@api.route('/<int:event_id>')\n@api.param('event_id')\n@api.response(404, 'Event not found')\nclass Event(Resource):\n    @api.doc('get_event')\n    @api.marshal_with(EVENT)\n    def get(self, event_id):\n        \"\"\"Fetch an event given its id\"\"\"\n        return DAO.get(event_id)\n\n    @requires_auth\n    @api.doc('delete_event')\n    @api.marshal_with(EVENT)\n    def delete(self, event_id):\n        \"\"\"Delete an event given its id\"\"\"\n        event = DAO.delete(event_id)\n        record_activity('delete_event', event_id=event_id)\n        return event\n\n    @requires_auth\n    @api.doc('update_event', responses=PUT_RESPONSES)\n    @api.marshal_with(EVENT)\n    @api.expect(EVENT_POST)\n    def put(self, event_id):\n        \"\"\"Update an event given its id\"\"\"\n        event = DAO.update(event_id, self.api.payload)\n        record_activity('update_event', event_id=event_id)\n        return event\n\n\n@api.route('')\nclass EventList(Resource, EventResource):\n    @api.doc('list_events', params=EVENT_PARAMS)\n    @api.marshal_list_with(EVENT)\n    def get(self):\n        \"\"\"List all events\"\"\"\n        return DAO.list(**parse_args(self.event_parser))\n\n    @requires_auth\n    @api.doc('create_event', responses=POST_RESPONSES)\n    @api.marshal_with(EVENT)\n    @api.expect(EVENT_POST)\n    def post(self):\n        \"\"\"Create an event\"\"\"\n        item = DAO.create(self.api.payload, self.api.url_for(self))\n        record_activity('create_event', event_id=item[0].id)\n        return item\n\n\n@api.route('/page')\nclass EventListPaginated(Resource, PaginatedResourceBase, EventResource):\n    @api.doc('list_events_paginated', params=PAGE_PARAMS)\n    @api.doc(params=EVENT_PARAMS)\n    @api.marshal_with(EVENT_PAGINATED)\n    def get(self):\n        \"\"\"List events in a paginated manner\"\"\"\n        args = self.parser.parse_args()\n        return get_paginated_list(\n            EventModel, args=args,\n            **parse_args(self.event_parser)\n        )\n\n\n@api.route('/<int:event_id>/links')\n@api.param('event_id')\nclass SocialLinkList(Resource):\n    @api.doc('list_social_links')\n    @api.marshal_list_with(SOCIAL_LINK)\n    def get(self, event_id):\n        \"\"\"List all social links\"\"\"\n        return LinkDAO.list(event_id)\n\n    @requires_auth\n    @api.doc('create_social_link', responses=POST_RESPONSES)\n    @api.marshal_with(SOCIAL_LINK_POST)\n    @api.expect(SOCIAL_LINK_POST)\n    def post(self, event_id):\n        \"\"\"Create a social link\"\"\"\n        return LinkDAO.create(\n            event_id,\n            self.api.payload,\n            self.api.url_for(self, event_id=event_id)\n        )\n\n\n@api.route('/<int:event_id>/links/<int:link_id>')\nclass SocialLink(Resource):\n    @requires_auth\n    @api.doc('delete_social_link')\n    @api.marshal_with(SOCIAL_LINK)\n    def delete(self, event_id, link_id):\n        \"\"\"Delete a social link given its id\"\"\"\n        return LinkDAO.delete(event_id, link_id)\n\n    @requires_auth\n    @api.doc('update_social_link', responses=PUT_RESPONSES)\n    @api.marshal_with(SOCIAL_LINK_POST)\n    @api.expect(SOCIAL_LINK_POST)\n    def put(self, event_id, link_id):\n        \"\"\"Update a social link given its id\"\"\"\n        return LinkDAO.update(event_id, link_id, self.api.payload)\n", "path": "open_event/api/events.py"}]}