From bd7f772589e7bb67e1748c1c97ed344783f2e864 Mon Sep 17 00:00:00 2001 From: Michelle Wei Date: Tue, 1 May 2018 03:16:06 -1000 Subject: [PATCH 1/4] add initial docs --- backend/actions.py | 27 ++++--- backend/database.py | 42 +++++++++++ backend/images.py | 34 ++++----- backend/main.py | 8 +-- backend/segment.py | 5 ++ docs/Makefile | 20 ++++++ docs/actions.rst | 7 ++ docs/conf.py | 159 +++++++++++++++++++++++++++++++++++++++++ docs/database.rst | 7 ++ docs/debug_backend.rst | 7 ++ docs/images.rst | 7 ++ docs/index.rst | 25 +++++++ docs/main.rst | 7 ++ docs/make.bat | 36 ++++++++++ docs/modules.rst | 11 +++ docs/segment.rst | 7 ++ docs/validate.rst | 7 ++ 17 files changed, 384 insertions(+), 32 deletions(-) create mode 100644 docs/Makefile create mode 100644 docs/actions.rst create mode 100644 docs/conf.py create mode 100644 docs/database.rst create mode 100644 docs/debug_backend.rst create mode 100644 docs/images.rst create mode 100644 docs/index.rst create mode 100644 docs/main.rst create mode 100644 docs/make.bat create mode 100644 docs/modules.rst create mode 100644 docs/segment.rst create mode 100644 docs/validate.rst diff --git a/backend/actions.py b/backend/actions.py index 8d18d56..b90e7c7 100644 --- a/backend/actions.py +++ b/backend/actions.py @@ -14,10 +14,11 @@ from images import save_image, get_image_by_uuid, get_image_as_b64 -def act_login(req): +def act_login(request): """Authenticates login with email and password - : param req: json request from client + :param request: json request from client + :returns: json of jwt """ params = request.get_json() username = params.get('username', None) @@ -34,7 +35,8 @@ def act_login(req): def act_list(username): """Lists the original and processed images for a user - :param username: client username + :param username: client username + :returns: json including uuid's of original and processed images """ return(jsonify({ 'originalID': get_original_image(username), @@ -42,10 +44,11 @@ def act_list(username): }), 200) -def act_upload(req): +def act_upload(request): """Uploads original user image - :param req: request from client + :param request: request from client + :returns: uuid of uploaded image """ params = request.get_json() username = params.get('username', None) @@ -60,10 +63,11 @@ def act_upload(req): return (jsonify({'fileID': uuid}), 200) -def act_process(req): +def act_process(request): """Processes the original image that has been uploaded - :param req: request from client + :param request: request from client + :returns: uuid of processed image """ username = request.get_json().get('username', None) @@ -76,11 +80,12 @@ def act_process(req): return (jsonify({'fileID': newUuid}), 200) -def act_download(req): - '''Handles download request for images +def act_download(request): + """Handles download request for images - :param req: json request from client - ''' + :param request: json request from client + :returns: b64 image string of processed image + """ params = request.get_json() fileID = params.get('fileID', None) filetype = params.get('filetype', None) diff --git a/backend/database.py b/backend/database.py index a17f2ef..dd6c9e0 100644 --- a/backend/database.py +++ b/backend/database.py @@ -14,6 +14,12 @@ class User(MongoModel): def add_user(username, password): + """Creates new user if user does not exist in the mongo database + + :param username: user email as string type which serves as user id + :param password: user password as string type + :returns: updates user information in mongo database + """ try: user = User.objects.raw({'_id': username}).first() except DoesNotExist: @@ -22,6 +28,10 @@ def add_user(username, password): def get_user(username): + """Gets user by unique username + :param username: user email as string type which serves as user id + :returns: user information + """ try: user = User.objects.raw({'_id': username}).first() return user @@ -30,6 +40,9 @@ def get_user(username): def delete_user(username): + """Deletes user from mongo database + :param username: user email as string type which serves as user id + """ try: user = User.objects.raw({'_id': username}).first() user.delete() @@ -40,6 +53,11 @@ def delete_user(username): def login_user(username, password): + """Returns true if user exists and has the correct password + :param username: user email as string type which serves as user id + :param password: user password as string type + :returns: True if user exists and has correct password, False if incorrect password + """ try: user = User.objects.raw({'_id': username}).first() if user.password and pbkdf2_sha256.verify(password, user.password): @@ -51,6 +69,11 @@ def login_user(username, password): def save_original_image_uuid(username, uuid): + """Updates existing user by adding the uuid of a user-uploaded image + :param username: user email as string type which serves as user id + :param uuid: universally unique identifier (UUID4) of user-uploaded image + :returns: adds uuid of user-uploaded image to mongo database + """ try: user = User.objects.raw({'_id': username}).first() user.original_image = uuid @@ -60,6 +83,11 @@ def save_original_image_uuid(username, uuid): def save_processed_image_uuid(username, uuid): + """Updates existing user by adding the uuid of the processed image + :param username: user email as string type which serves as user id + :param uuid: universally unique identifier (UUID4) of processed image + :returns: adds uuid of processed image to mongo database + """ try: user = User.objects.raw({'_id': username}).first() user.processed_image = uuid @@ -69,6 +97,10 @@ def save_processed_image_uuid(username, uuid): def get_original_image(username): + """Gets the original image uuid for a user + :param username: user email as string type which serves as user id + :returns: uuid (UUID4) of user's original image as a string + """ try: user = User.objects.raw({'_id': username}).first() return user.original_image @@ -77,6 +109,10 @@ def get_original_image(username): def get_processed_image(username): + """Gets the processed image uuid for a user + :param username: user email as string type which serves as user id + :returns: uuid (UUID4) of user's processed image as a string + """ try: user = User.objects.raw({'_id': username}).first() return user.processed_image @@ -85,6 +121,9 @@ def get_processed_image(username): def delete_image(name): + """Deletes image stored in server + :param name: name (uuid as a string) of an image stored in the VM server + """ for f in os.listdir('images/'): if f.startswith(name): os.remove('images/' + f) @@ -92,6 +131,9 @@ def delete_image(name): def remove_images(username): + """Removes all images associated with a user + :param username: user email as string type which serves as user id + """ try: user = User.objects.raw({'_id': username}).first() if user.original_image is not None: diff --git a/backend/images.py b/backend/images.py index beac7dc..d99d61f 100644 --- a/backend/images.py +++ b/backend/images.py @@ -9,10 +9,11 @@ def save_image(img_str): - '''Converts image string to binary and saves onto drive + """Converts image string to binary and saves onto drive - :param img_str: base64 image string - :return uuid: UUID4 of image''' + :param img_str: base64 image string + :returns uuid of image + """ uuid = uuid4().hex str_parts = img_str.split(',') @@ -34,10 +35,11 @@ def save_image(img_str): def save_image_from_arr(img_arr): - '''Converts uint array to png file (intermediary format stored on server) + """Converts uint array to png file (intermediary format stored on server) - :param img_arr: uint array - :return uuid: uuid of converted image''' + :param img_arr: uint array of image + :returns uuid of image + """ uuid = uuid4().hex img = Image.fromarray(img_arr) @@ -46,13 +48,11 @@ def save_image_from_arr(img_arr): def get_image_by_uuid(uuid): - '''Converts image base64 string to uint array, saves intermediate image - file to server + """Retrieves uint array of image by its uuid - :param img_str: base64 image string - :param uuid: UUID of image to save - :return data: grayscale image array - ''' + :param uuid: UUID of image as string + :returns: grayscale image array + """ for f in os.listdir('images/'): if re.match(uuid, f): @@ -65,12 +65,12 @@ def get_image_by_uuid(uuid): def get_image_as_b64(uuid, filetype='png'): - '''Gets b64 image string by uuid + """Gets b64 image string by uuid - :param uuid: uuid of image - :param filetype: file type to output, options are jpeg, png, or gif - :return: b64 string of image - ''' + :param uuid: uuid of image + :param filetype: file type to output, options are jpeg, png, or gif + :returns: b64 string of image + """ filetype = filetype.lower() img_format = None diff --git a/backend/main.py b/backend/main.py index 1756109..a32e885 100644 --- a/backend/main.py +++ b/backend/main.py @@ -17,10 +17,10 @@ def handler(input, validator, action): """Handles API endpoints - :param input: input data from request - :param validator: validator function to use - :param action: database function to apply to data - :return: jsonified response + :param input: input data from request + :param validator: validator function to use + :param action: database function to apply to data + :return: jsonified response """ if not request.is_json: diff --git a/backend/segment.py b/backend/segment.py index 262f6f6..bfcdf6e 100644 --- a/backend/segment.py +++ b/backend/segment.py @@ -6,6 +6,11 @@ def segment(uuid): + """Segments image with input uuid, saves processed image to server and returns its uuid + + :param uuid: uuid of original image + :returns: uuid of processed image and saves the b64 string of image on server + """ uintfile = get_image_by_uuid(uuid) val = filters.threshold_otsu(uintfile) hist, bins_center = exposure.histogram(uintfile) diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..c0b100a --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +SPHINXPROJ = ImageProcessorS18 +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) \ No newline at end of file diff --git a/docs/actions.rst b/docs/actions.rst new file mode 100644 index 0000000..dd207e2 --- /dev/null +++ b/docs/actions.rst @@ -0,0 +1,7 @@ +actions module +============== + +.. automodule:: actions + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..0b77894 --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,159 @@ +# -*- coding: utf-8 -*- +# +# Configuration file for the Sphinx documentation builder. +# +# This file does only contain a selection of the most common options. For a +# full list see the documentation: +# http://www.sphinx-doc.org/en/master/config + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +import os +import sys +sys.path.insert(0, os.path.abspath('..')) + + +# -- Project information ----------------------------------------------------- + +project = 'ImageProcessorS18' +copyright = '2018, Harvey Shi, Edward Liang, Michelle Wei' +author = 'Harvey Shi, Edward Liang, Michelle Wei' + +# The short X.Y version +version = '' +# The full version, including alpha/beta/rc tags +release = 'v1.0.0' + + +# -- General configuration --------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx.ext.autodoc', +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path . +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'alabaster' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# +# html_theme_options = {} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# Custom sidebar templates, must be a dictionary that maps document names +# to template names. +# +# The default sidebars (for documents that don't match any pattern) are +# defined by theme itself. Builtin themes are using these templates by +# default: ``['localtoc.html', 'relations.html', 'sourcelink.html', +# 'searchbox.html']``. +# +# html_sidebars = {} + + +# -- Options for HTMLHelp output --------------------------------------------- + +# Output file base name for HTML help builder. +htmlhelp_basename = 'ImageProcessorS18doc' + + +# -- Options for LaTeX output ------------------------------------------------ + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'ImageProcessorS18.tex', 'ImageProcessorS18 Documentation', + 'Harvey Shi, Edward Liang, Michelle Wei', 'manual'), +] + + +# -- Options for manual page output ------------------------------------------ + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'imageprocessors18', 'ImageProcessorS18 Documentation', + [author], 1) +] + + +# -- Options for Texinfo output ---------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'ImageProcessorS18', 'ImageProcessorS18 Documentation', + author, 'ImageProcessorS18', 'One line description of project.', + 'Miscellaneous'), +] + + +# -- Extension configuration ------------------------------------------------- \ No newline at end of file diff --git a/docs/database.rst b/docs/database.rst new file mode 100644 index 0000000..2a994fe --- /dev/null +++ b/docs/database.rst @@ -0,0 +1,7 @@ +database module +=============== + +.. automodule:: database + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/debug_backend.rst b/docs/debug_backend.rst new file mode 100644 index 0000000..62ebc2b --- /dev/null +++ b/docs/debug_backend.rst @@ -0,0 +1,7 @@ +debug\_backend module +===================== + +.. automodule:: debug_backend + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/images.rst b/docs/images.rst new file mode 100644 index 0000000..b44f95a --- /dev/null +++ b/docs/images.rst @@ -0,0 +1,7 @@ +images module +============= + +.. automodule:: images + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..ae73315 --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,25 @@ +.. ImageProcessorS18 documentation master file, created by + sphinx-quickstart on Tue May 1 02:17:54 2018. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to ImageProcessorS18's documentation! +============================================= + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + +.. automodule:: segment +.. automodule:: actions +.. automodule:: database +.. automodule:: images +.. automodule:: main + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/docs/main.rst b/docs/main.rst new file mode 100644 index 0000000..e8ec7e4 --- /dev/null +++ b/docs/main.rst @@ -0,0 +1,7 @@ +main module +=========== + +.. automodule:: main + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 0000000..6c6654a --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,36 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=. +set BUILDDIR=_build +set SPHINXPROJ=ImageProcessorS18 + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% + +:end +popd diff --git a/docs/modules.rst b/docs/modules.rst new file mode 100644 index 0000000..9525122 --- /dev/null +++ b/docs/modules.rst @@ -0,0 +1,11 @@ +ImageProcessorS18 +================= + +.. toctree:: + :maxdepth: 4 + + segment + actions + database + images + main \ No newline at end of file diff --git a/docs/segment.rst b/docs/segment.rst new file mode 100644 index 0000000..c9d6212 --- /dev/null +++ b/docs/segment.rst @@ -0,0 +1,7 @@ +segment module +============== + +.. automodule:: segment + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/validate.rst b/docs/validate.rst new file mode 100644 index 0000000..73c9370 --- /dev/null +++ b/docs/validate.rst @@ -0,0 +1,7 @@ +validate module +=============== + +.. automodule:: validate + :members: + :undoc-members: + :show-inheritance: From e515162627869de17947989c081a1657ab3b2908 Mon Sep 17 00:00:00 2001 From: Michelle Wei Date: Tue, 1 May 2018 03:23:11 -1000 Subject: [PATCH 2/4] pep 8 revisions --- backend/database.py | 10 +++++----- backend/images.py | 9 +++------ backend/segment.py | 5 +++-- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/backend/database.py b/backend/database.py index dd6c9e0..1a0dc48 100644 --- a/backend/database.py +++ b/backend/database.py @@ -56,7 +56,7 @@ def login_user(username, password): """Returns true if user exists and has the correct password :param username: user email as string type which serves as user id :param password: user password as string type - :returns: True if user exists and has correct password, False if incorrect password + :returns: True if user has correct password, False if incorrect password """ try: user = User.objects.raw({'_id': username}).first() @@ -71,7 +71,7 @@ def login_user(username, password): def save_original_image_uuid(username, uuid): """Updates existing user by adding the uuid of a user-uploaded image :param username: user email as string type which serves as user id - :param uuid: universally unique identifier (UUID4) of user-uploaded image + :param uuid: UUID4 of user-uploaded image :returns: adds uuid of user-uploaded image to mongo database """ try: @@ -85,7 +85,7 @@ def save_original_image_uuid(username, uuid): def save_processed_image_uuid(username, uuid): """Updates existing user by adding the uuid of the processed image :param username: user email as string type which serves as user id - :param uuid: universally unique identifier (UUID4) of processed image + :param uuid: UUID4 of processed image :returns: adds uuid of processed image to mongo database """ try: @@ -99,7 +99,7 @@ def save_processed_image_uuid(username, uuid): def get_original_image(username): """Gets the original image uuid for a user :param username: user email as string type which serves as user id - :returns: uuid (UUID4) of user's original image as a string + :returns: uuid of user's original image as a string """ try: user = User.objects.raw({'_id': username}).first() @@ -122,7 +122,7 @@ def get_processed_image(username): def delete_image(name): """Deletes image stored in server - :param name: name (uuid as a string) of an image stored in the VM server + :param name: name (uuid) of an image stored in the VM server """ for f in os.listdir('images/'): if f.startswith(name): diff --git a/backend/images.py b/backend/images.py index d99d61f..469c3e7 100644 --- a/backend/images.py +++ b/backend/images.py @@ -1,7 +1,7 @@ import base64 import numpy as np from PIL import Image -from mimetypes import guess_extension +# from mimetypes import guess_extension from uuid import uuid4 import re import os @@ -12,9 +12,8 @@ def save_image(img_str): """Converts image string to binary and saves onto drive :param img_str: base64 image string - :returns uuid of image + :returns: uuid of image """ - uuid = uuid4().hex str_parts = img_str.split(',') @@ -38,9 +37,8 @@ def save_image_from_arr(img_arr): """Converts uint array to png file (intermediary format stored on server) :param img_arr: uint array of image - :returns uuid of image + :returns: uuid of image """ - uuid = uuid4().hex img = Image.fromarray(img_arr) img.save('images/{}.png'.format(uuid), 'PNG') @@ -53,7 +51,6 @@ def get_image_by_uuid(uuid): :param uuid: UUID of image as string :returns: grayscale image array """ - for f in os.listdir('images/'): if re.match(uuid, f): im = Image.open('images/' + f) diff --git a/backend/segment.py b/backend/segment.py index bfcdf6e..a6259c4 100644 --- a/backend/segment.py +++ b/backend/segment.py @@ -6,10 +6,11 @@ def segment(uuid): - """Segments image with input uuid, saves processed image to server and returns its uuid + """Segments image with input uuid, saves processed image to server + and returns its uuid :param uuid: uuid of original image - :returns: uuid of processed image and saves the b64 string of image on server + :returns: uuid of processed image, saves b64 string of image on server """ uintfile = get_image_by_uuid(uuid) val = filters.threshold_otsu(uintfile) From d62a6980de9ceea1508129862d0e75cc5a49d9c1 Mon Sep 17 00:00:00 2001 From: Michelle Wei Date: Tue, 1 May 2018 03:26:16 -1000 Subject: [PATCH 3/4] pep 8 on database.py --- backend/database.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/database.py b/backend/database.py index 1a0dc48..7672618 100644 --- a/backend/database.py +++ b/backend/database.py @@ -56,7 +56,7 @@ def login_user(username, password): """Returns true if user exists and has the correct password :param username: user email as string type which serves as user id :param password: user password as string type - :returns: True if user has correct password, False if incorrect password + :returns: True if password is correct, False if incorrect """ try: user = User.objects.raw({'_id': username}).first() From 8f550969231857696383c037c12cb314811d86cf Mon Sep 17 00:00:00 2001 From: Michelle Wei Date: Tue, 1 May 2018 03:34:12 -1000 Subject: [PATCH 4/4] docs conf.py path change --- docs/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index 0b77894..995a890 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -14,7 +14,7 @@ # import os import sys -sys.path.insert(0, os.path.abspath('..')) +sys.path.insert(0, os.path.abspath('../backend/')) # -- Project information -----------------------------------------------------