This application was created as my submission for project 4 of Udacity's Full Stack Nanodegree program. The objective of project 4 is develop a EndPoints using Google's App Engine. All of the work done was focused on the back end and creating the API.
Sessions are the individual events that make up a conference. Sessions can have several formats. Workshop, Lecture, Keynote, Demo and Panel have been provided as options for the SessionType. Since you can not have a session without a conference, sessions require a conference key to be passed under parentConfKey. This conference key is used to establish an ancestor relationship between the conference and the session. In addition to parentConfKey, the name property is also a required field. To prevent unwanted sessions being created, only the creator of a conference can add sessions to it.
Property | Data Type Choice |
---|---|
name | StringProperty(required=True) Used string here since the name of the session will be unicode and required this since a session needs a name. |
highlights | StringProperty() Highlights will be unicode and shouldn't be more than 1500 bytes so used string instead of text here. |
speakerKey | StringProperty(repeated=True) Since a urlsafe key will be made of unicode character, chose a string here and allowed repeat to accommodate multiple speakers. |
duration | IntegerProperty() I chose integer for duration to store duration as number of minutes. I chose to use minutes for duration to aid with inequality filters. |
typeOfSession | StringProperty(default='Not_Specified') I chose to use enum values for typeOfSession to limit choices of type. String is used in the message class to allow it to be passed through HTTP. |
date | DateProperty() I chose to use a DateProperty here to aid the use of inequality filters. |
month | IntegerProperty() I chose to use an integer here since months can easily be represented as 1-12 and this too aids inequality filters. |
startTime | TimeProperty() I chose a time property here to allow for searching of times before and/or after a desired time (inequality filters). |
parentConfKey | StringProperty(required=True) Since a urlsafe key will be made of unicode character, chose a string here and made this a required field since sessions have an ancestor relationship with conferences. |
In their current capacity, speakers are associated with most sessions as the main attraction. Since a speaker can attend more than one session, or even more than one conference, speakers are there own entity with the following properties: name, briefBio, company and projects. name is the only required property for a speaker. A speaker has no ancestor relationship since a speaker can attend multiple conferences and sessions.
Property | Data Type Choice |
---|---|
name | StringProperty(required=True) I chose a string here since a speakers name should be unicode. Required this field since a speaker must have a name. |
briefBio | StringProperty() A brief bio should not exceed 1500 characters (bytes) so chose a string instead of text here. |
company | StringProperty(repeated=True) A company's name should be unicode so chose string here. Allow multiple companies for speakers with multiple. |
projects | StringProperty(repeated=True) A project's name should be unicode so chose string here. Allow multiple projects since speakers will most likely have more than one project. |
A speaker is added to a session using the speaker's key, through the session's speakerKey. A session's speakerKey property allows for more than one speaker since sessions can have multiple speakers or a panel. Each key is passed is verified individually and an exception is thrown if one is invalid.
A featured speaker is defined as a speaker that is assigned to two or more
sessions within a conference. When a session is created within
_createSessionObject()
, a check is performed on each speakerKey that is
passed in. For each speakerKey, the number of sessions for the speaker is
calculated. The speaker with the most sessions is then set as the featured
speaker and added to the task queue through _cacheFeaturedSpeaker()
to be
added to memcache. If there is a tie for number of sessions, the last speaker
passed is assigned the featured speaker.
A User can add sessions to their wish list using addSessionToWishlist()
and
passing in the session key. A user must be registered to the parent
conference of a session to add it to their wish list. The session's key is
added to the user's profile under the sessionWishList property. Since a
session's key is unicode, I chose to use StringProperty() for the data type.
A user can also remove a session from their wish list using
removeSessionFromWishlist()
. Additionally you can retrieve all sessions in
a user's wish list by calling getSessionWishlist() while a user is authed.
getSpeakersByConference()
takes in a conference key and returns all speakers in that conference, regardless of session. This can be used to quickly see the speaker lineup for an entire conference.getConferenceSessionsByDate()
takes in a conference key and date to return all sessions for the parent conference matching the specified date. This would allow a participant to decided what days might be more valuable to them based on the sessions that are available.
Question posed in project: Let’s say that you don't like workshops and you don't like sessions after 7 pm. How would you handle a query for all non- workshop sessions before 7 pm? What is the problem for implementing this query? What ways to solve it did you think of?
The problem here is that we are trying to perform inequality filters on two separate properties. Within Datastore, inequality filters can only be applied to one property. Additionally, any properties with an inequality filter must be sorted first, all though this is not an issue with the above problem.
- Comparing two separate queries: The first solution that I thought of was
to perform two separate queries, one for sessions no later then 7pm and another
for sessions that are not workshops. With both of these queries complete, the
results can then be compared and only the matching sessions will be returned as
the result.
This was the solution that I used ingetConferenceSessionsByTimeAndType()
- Filter results programmatically: This solution would perform a query on the database and then filter the results using the language of choice; Python in this case. In the above example, we could query for sessions that are not workshops and store them locally. We could then filter the stored results by startTime.
- Combinding properties into new property: This is a solution that I found
through a bit of Googling that peaked my interest. From what I have read, this
would be a great solution for larger data bases that have a specific multi-
property inequality filter that is used frequently. Essentially we would need
to rewrite the Model and session creation function so that the startTime
property and typeOfSession property could be combined into a new value.
This one was a little over my head, but I found it interesting enough to include.
File | Description |
---|---|
conference.py | This is the main Python file which contains the ConferenceApi(). |
models.py | This Python file holds the Model and Message structures for Google's Datastore (ndb). |
main.py | This Python file contains the HTTP controller handlers for memcache & task queue. |
settings.py | This Python file holds a user's client IDs. This file will need to be updated if you are wanting to deploy the application. |
utils.py | This Python file holds a utility function to grab a user's ID. |
app.yaml | Google App Engine configuration file containing application and path information. |
cron.yaml | Google App Engine configuration file containing settings for scheduled tasks. |
index.yaml | Google App Engine configuration file containing indexes for queries. |
templates Folder | Stores the main HTML template for the application. |
static Folder | Stores all dependencies/resources for the HTML templates, including partials.. |
####Prerequisites:
Prerequisite | Documentation | Download |
---|---|---|
Git | docs | download |
Python 2.7 | docs | download |
Google App Engine SDK | docs | download |
- Open terminal:
- Windows: Use the Git Bash program (installed with Git) to get a Unix-style terminal.
- Other systems: Use your favorite terminal program.
- Change to the desired parent directory
- Example:
cd Desktop/
- Using Git, clone this project:
- Run:
git clone https://github.com/gravic07/Conference_Central.git Conference_Central
- This will create a directory inside of your parent directory titled Conference_Central.
- Download the Google App Engine SDK for Python using the link listed under Prerequisites.
- Once the SDK is installed, open GoogleAppEngineLauncher.
- Under File, select Add Existing Application....
- Select Browse and navigate to the newly created Conference_Central Folder.
- (Optional) Adjust the Admin Port and Port if desired and make note of both.
- With the newly added application highlighted, press Run.
- The APIs explorer should now be available at http://localhost:8080/_ah/api/explorer
- The url above assumes the default port. If Port was altered in step 8, replace 8080 with the new port provided.
- Select conference API to access all EndPoints.
- addSessionToWishlist - Adds an existing session to the authed user's wish list using the Session's key.
- createConference - Creates a conference; name property is required.
- createSession - Creates a session; name and parentConfKey properties are required.
- createSpeaker - Creates a ppeaker; name property is required.
- getAnnouncement - Retrieve announcement for conferences that are almost sold out.
- getConfSessionsByDate - Retrieve sessions by conference key and date.
- getConfSessionsByType - Retrieve sessions by conference key and session type.
- getConference - Retrieve conference by conference key.
- getConferencesCreated - Retrieve conference created by authed user.
- getConferencesToAttend - Retrieve conferences that authed user has registered for.
- getFeaturedSpeaker - Retrieve the current featured speaker from memcache.
- getProfile - Retrieve the profile of the current authed user.
- getSessionWishlist - Retrieve the session wish list for the current authed user.
- getSessionsByConference - Retrieve all sessions by conference key.
- getSessionsBySpeaker - Retrieve all sessions by speaker key.
- getSpeakersByConference - Retrieve all speakers by conference key.
- queryConferences - Retrieve conferences based on custom filters.
- registerForConference - Register the authed user for a conference using the conference key.
- removeSessionFromWishlist - Removes a session from the authed user's Wishlist using the session's key.
- saveProfile - Saves the authed user's profile after editing.
- unregisterFromConference - Unregister the authed user for a conference using the conference key.
In the off chance someone would like to contribute to this project, follow the usual steps:
- Fork it!
- Create your feature branch:
git checkout -b my-new-feature
- Commit your changes:
git commit -am 'Add some feature'
- Push to the branch:
git push origin my-new-feature
- Submit a pull request :D
Base code provided by Udacity and edited by gravic07
See License