Lab Assignment 6 (CS328 only): A url-shortening service

In this assignment you will be creating a small url-shortening and bookmarking service. The idea of this service is as follows:

Submission information

You can get the start files for this project by "cloning" the repository at https://github.com/skiadas/linky.git. There are start files there for you to work with. You can clone this repository by going to an appropriate location in your terminal, and run the commands:

git clone https://github.com/skiadas/linky.git
cd linky

Here are the files included in this folder, named linky:

When you are ready to submit your assignment, you should create a zip file of the linky folder, and email it to me. To create a zip file you can go to the parent directory of the linky folder in the terminal, and run the command:

zip -r yourFavoriteName.zip linky

Database requirements

Your database file should follow the structure of the sample db.py, and use ORM to introduce needed classes, followed by a Db class that represents a connection to the database. A start on these has been done for you. Here are the classes you should have:

Tasks, part 1: Add the suitable lines to db.py to set up the above classes. Tasks, part 2: Your Db class should provide at least the following methods (there are tests provided for these methods in the tests.py file, make sure you can pass those tests, and you should add your own as well):

  1. A method getBuckets(self) that returns a list of all buckets in the system. The result should be a (possibly empty) list of Bucket objects.
  2. A method addBucket(self, id, passwordHash, description=None) that can be used to create a new bucket in the database. The method should return the created bucket object. This method does NOT need to check if a bucket with that id already exists, that's the job of its caller.
  3. A method getBucket(self, id) that is given a bucket id and searches in the database for a bucket with that id. Returns either the Bucket object with that id, or None.
  4. A method deleteBucket(self, bucket) that can be used to delete an existing bucket. It expects to be given a bucket object, and deletes it from the database.
  5. A method addShortcut(self, linkHash, bucket, link, description=None) which creates a new shortcut entry in the database. It expects to take a shortcut string, a Bucket object, a link string and optionally a description string. It does NOT need to check if an entry with the same primary keys exists, that's the job of its caller.
  6. A method getShortcut(self, linkHash, bucket) that searches for a shortcut with a given hash string and belonging to a given bucket, and returns it if one exists (or returns None otherwise).
  7. A method deleteShortcut(self, shortcut) that is given a Shortcut object and deletes it.

Web Service requirements

You will implement the following web service routes (details on them follow):

Route Scheme Function Name Role
GET '/' bucket_list List of all buckets
GET '/<bucketId>' bucket_contents Contents of a bucket
POST '/' bucket_create Create a new bucket
PUT '/<bucketId>' bucket_create_with_id Create a new bucket
DELETE '/<bucketId>' bucket_delete Delete a bucket
GET '/<bucketId>/<hash>' shortcut_get_link Get a shortcut link
POST '/<bucketId>' shortcut_create Create a shortcut link
PUT '/<bucketId>/<hash>' shortcut_create_with_hash Create a shortcut link
DELETE '/<bucketId>/<hash>' shortcut_delete Delete a shortcut link

Add tests for these in the tests.py file. The file has some initial entries created for you

Tasks, part 3: You must implement the following services. You may create any helper functions you like, similar to what we did in the banking-flask project.

  1. GET '/' is meant to return a list of all the available buckets, and it is implemented in the function bucket_list. You should return a payload that looks as follows:

    {
        "buckets": [
            {
                "link": "/<bucketID>",
                "description": "the bucket description"
            },
            ...
        ]
    }
    You can use a list comprehension over the result of the database query to create that list of bucket entries. Use url_for to create the links.
  2. GET '/<bucketId>' returns information about a particular bucket. It is implemented in the function bucket_contents. Its behavior should be as follows:

  3. PUT '/<bucketId>' is used to create a new bucket with a given id provided by the user. It is implemented in the bucket_create_with_id function. Its behavior should be as follows:

  4. POST '/' is used to create a new bucket with an automatically-generated id. It is implemented by the bucket_create function. It behaves similarly to the PUT version above, with a small variation:

  5. DELETE '/<bucketId>' is used to delete a bucket. It is implemented in the bucket_delete function. Its behavior should be as follows:

  6. GET '/<bucketId>/<hash>' is a method used to retrieve a shortcut. It is implemented in the function shortcut_get_link. Its behavior should be as follows:

  7. PUT '/<bucketId>/<hash>' is used to create new shortcuts. It is implemented by the function shortcut_create_with_hash. Its behavior should be as follows:

  8. POST '/<bucketId>' can also be used to create new shortcuts, where the client expects the linkHash to be generated by the server. It is implemented by the function shortcut_create. Its behavior should be as follows:

  9. DELETE '/<bucketId>/<linkHash>' is used to delete a shortcut. It is implemented by the shortcut_delete function. Its behavior should be as follows: