From c894551bd8ff5a64b648f7e837cb9f88b69ce5e6 Mon Sep 17 00:00:00 2001 From: Justin Campbell Date: Tue, 23 Mar 2021 21:39:17 -0400 Subject: [PATCH 01/35] Add variable support to mkdocs --- mkdocs.yml | 4 ++++ setup.py | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/mkdocs.yml b/mkdocs.yml index bc8596a..b7ee5b1 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -11,6 +11,9 @@ plugins: # See: https://github.com/lukasgeiter/mkdocs-awesome-pages-plugin - awesome-pages: filename: awesome-pages.yaml + # Macros Settings + # See: https://squidfunk.github.io/mkdocs-material/reference/variables/ + - macros markdown_extensions: - toc: permalink: ⚓︎ @@ -56,6 +59,7 @@ extra: - icon: fontawesome/brands/github link: https://github.itap.purdue.edu/ECN/webqueue2 name: webqueue2 on GitHub + production_url: "https://engineering.purdue.edu/webqueue/webqueue2/build" extra_javascript: - https://cdnjs.cloudflare.com/ajax/libs/tablesort/5.2.1/tablesort.min.js diff --git a/setup.py b/setup.py index abb6552..c6cfdac 100644 --- a/setup.py +++ b/setup.py @@ -9,7 +9,8 @@ "mkdocs", "mkdocs-material", "mkautodoc", - "mkdocs-awesome-pages-plugin" + "mkdocs-awesome-pages-plugin", + "mkdocs-macros-plugin" ], } From b3efaf46c2060450c6d673f50760747d90016939 Mon Sep 17 00:00:00 2001 From: Justin Campbell Date: Tue, 23 Mar 2021 21:56:34 -0400 Subject: [PATCH 02/35] Update docs to include production URL variable --- docs/api/Authentication.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/api/Authentication.md b/docs/api/Authentication.md index 1cedd3e..5436bf3 100644 --- a/docs/api/Authentication.md +++ b/docs/api/Authentication.md @@ -20,7 +20,7 @@ All API calls require an access token. You can get an access token by making a P body: JSON.stringify({ "username": USERNAME, "password": PASSWORD}) }; - let loginResponse = await fetch("API_URL/api/login", loginInit); + let loginResponse = await fetch("{{ production_url }}/api/login", loginInit); let data = await loginResponse.json(); if (data === null){ @@ -51,7 +51,7 @@ All API calls require an access token. You can get an access token by making a P request = POST header = "Content-Type: application/json" data = {"username":"USERNAME","password":"PASSWORD"} - url = "API_URL/api/login" + url = "{{ production_url }}/api/login" ``` Restrict read permissions to your user: From 1a2035330a0e7ee93af1e2927ca7ab1811119e8b Mon Sep 17 00:00:00 2001 From: Justin Campbell Date: Wed, 24 Mar 2021 00:23:07 -0400 Subject: [PATCH 03/35] Update auth docs to include fetch/curl examples for getting, passing and refreshing tokens --- docs/api/Authentication.md | 128 ++++++++++++++++++++++++++++++++++++- mkdocs.yml | 2 + 2 files changed, 128 insertions(+), 2 deletions(-) diff --git a/docs/api/Authentication.md b/docs/api/Authentication.md index 5436bf3..3c54581 100644 --- a/docs/api/Authentication.md +++ b/docs/api/Authentication.md @@ -2,6 +2,7 @@ The webqueue2 API uses a two stage authentication system combining Active Directory and [HTTP Token](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication) (or "bearer") authentication. +## Getting an Access Token All API calls require an access token. You can get an access token by making a POST request to the `/api/login` endpoint containing the JSON encoded username and password of a valid user. ??? info "Who is a valid user?" @@ -52,6 +53,8 @@ All API calls require an access token. You can get an access token by making a P header = "Content-Type: application/json" data = {"username":"USERNAME","password":"PASSWORD"} url = "{{ production_url }}/api/login" + # Save cookies for future API calls + cookies = "wq_cookies" ``` Restrict read permissions to your user: @@ -65,7 +68,7 @@ All API calls require an access token. You can get an access token by making a P ``` ``` # Expected Output: - {"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE2MTYxODI1MjMsIm5iZiI6MTYxNjE4MjUyMywianRpIjoiYzI2ZjY4NDctZGU2OC00ODUzLWI4ODctMTBmZDAyMDcyY2U0IiwiZXhwIjoxNjE2MTgzNDIzLCJzdWIiOiJjYW1wYjMwMyIsImZyZXNoIjpmYWxzZSwidHlwZSI6ImFjY2VzcyIsImNzcmYiOiJjYjYzZWE1My1jOWQ2LTQ5YTItYmZhMi0wY2U4N2Q3YzcxZDcifQ.T7bezsOMreMCXWR0R5w5BKI673hpOquCOnvT1XkyDjY"} + {"access_token": "{{ example_access_token }}"} ``` ??? tip "Tip for Parsing Tokens in Bash" @@ -73,4 +76,125 @@ All API calls require an access token. You can get an access token by making a P ```bash curl -K ~/wq_login.config | \ python3 -c "import sys, json; print(json.load(sys.stdin)['access_token'])" - ``` \ No newline at end of file + ``` + +## Making Calls With Access Token +To interact with the API, add an `Authorization` header to your request with a value of `Bearer TOKEN` where `TOKEN` is your access token. + +Example: Get item `ce100` +=== "fetch" + ```javascript + const ce100 = (async _ => { + const loginInit = { + method: "GET", + headers: {'Authentication': 'Bearer {{ example_access_token }}'}, + }; + + let apiResponse = await fetch("{{ production_url }}/api/data/ce/100", loginInit); + let data = await apiResponse.json(); + + if (data === null){ + return false; + } + + if (!apiResponse.ok){ + console.error(`Fetching item ce100 failed. Got code ${apiResponse.status} (${apiResponse.statusText})`); + return false; + } + + return data || false; + })(); + ``` + +=== "cURL" + Create a cURL config file named `wq_get_ce100.config`: + ```bash + nano ~/wq_get_ce100.config + ``` + + Set cURL options + ```python + # ~/wq_get_ce100.config + request = GET + header = "Authorization: Bearer {{ example_access_token }}" + url = "{{ production_url }}/api/data/ce/100" + ``` + + Run cURL using your new config file: + ```bash + curl -K ~/wq_get_ce100.config + ``` + ``` + # Expected Output: + { 'assignedTo': 'campb303', 'building': '', 'content': [...], 'dateReceived': '2020-06-23T13:25:51-0400', 'department': '', 'headers': [...], 'isLocked': 'ce 100 is locked by knewell using qvi', 'lastUpdated': '2020-12-01T19:53:00-0500', 'number': 100, 'priority': '', 'queue': 'ce', 'status': 'Dont Delete', 'subject': 'Beepboop', 'userAlias': 'campb303', 'userEmail': 'campb303@purdue.edu', 'userName': 'Justin Campbell' } + ``` + +## Refreshing Access Tokens +By default, access tokens expire 15 minutes after being issued and need refreshed. During login, you'll receive two cookies: + +Name | Value | Path | Expiration | SameSite +-- | -- | -- | -- | -- +`refresh_token_cookie` | Your refresh token. | `/api/tokens/refresh` | 30 Days | Yes +`csrf_refresh_token` | Additional verification data. (e.g. `{{ example_csrf_token }}`) | `/` | Session | Yes + +The `refresh_token_cookie` is used to generate a new access token and will be sent back to the server with every request automatically. The `csrf_refresh_token` is used to verify the `refresh_token_cookie` and needs sent back as an `X-CSRF-TOKEN` header. + +To refresh your access token, make a POST request to the `/api/tokens/refresh` endpoint with the value of the `csrf_refresh_token` cookies inside a `X-CSRF-TOKEN` header: + +=== "fetch" + ```javascript + const newAccessToken = (async _ => { + const csrf_refresh_token = some_func_to_get_csrf_token(); + + const refreshInit = { + method: "POST", + headers: {'X-CSRF-TOKEN': csrf_refresh_token}, + }; + + let refreshResponse = await fetch(`{{ production_url }}/api/tokens/refresh`, refreshInit); + let data = await refreshResponse.json(); + + if (data === null){ + return false; + } + if (!refreshResponse.ok){ + console.error(`Refresh failed. Got code ${refreshResponse.status} (${refreshResponse.statusText})`); + return false; + } + + return data.access_token || false; + })(); + ``` + +=== "cURL" + Create a cURL config file named `wq_refresh.config`: + ```bash + nano ~/wq_refresh.config + ``` + + Set cURL options + ```python + # ~/wq_refresh.config + request = POST + header = "X-CSRF-TOKEN: {{ example_csrf_token }}" + url = "{{ production_url }}/api/tokens/refresh" + # Pull cookies from login. + cookie-jar = "wq_cookies" + ``` + + Run cURL using your new config file: + ```bash + curl -K ~/wq_refresh.config + ``` + ``` + # Expected Output: + {"access_token": "{{ example_access_token }}"} + ``` + + ??? tip "Tip for Parsing Tokens in Bash" + You can parse the access token using Python like this: + ```bash + curl -K ~/wq_login.config | \ + python3 -c "import sys, json; print(json.load(sys.stdin)['access_token'])" + ``` + ``` \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index b7ee5b1..37596d7 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -60,6 +60,8 @@ extra: link: https://github.itap.purdue.edu/ECN/webqueue2 name: webqueue2 on GitHub production_url: "https://engineering.purdue.edu/webqueue/webqueue2/build" + example_access_token: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE2MTY1NTIyMDIsIm5iZiI6MTYxNjU1MjIwMiwianRpIjoiZDgyNGM1MWItM2JmNy00ZDUzLWE0YTgtY2VhZWQ5ZmVjNGYzIiwiZXhwIjoxNjE2NTUzMTAyLCJzdWIiOiJjYW1wYjMwMyIsImZyZXNoIjpmYWxzZSwidHlwZSI6ImFjY2VzcyIsImNzcmYiOiI1Yjk5NWQ5OS05YjIzLTQyMjYtYTc0OC1lMmQ5OTA4MDkzOTQifQ.6z7EReDfhPkBkuAMHEvDuMDV4wVbqrWSjQXdRyv_5hE" + example_csrf_token: "7b7c1ea8-f6bb-4204-99af-cd4124a69d89" extra_javascript: - https://cdnjs.cloudflare.com/ajax/libs/tablesort/5.2.1/tablesort.min.js From 0d7ccfafe4ca3e4442c8ebe9b400be1a505b5176 Mon Sep 17 00:00:00 2001 From: benne238 Date: Mon, 29 Mar 2021 08:35:45 -0400 Subject: [PATCH 04/35] style changes to the backend documentation --- docs/css/custom_css.css | 37 +++ docs/ecnqueue.md | 15 +- webqueue2_api/ECNQueue.py | 665 ++++++++++++++++++++++---------------- 3 files changed, 438 insertions(+), 279 deletions(-) diff --git a/docs/css/custom_css.css b/docs/css/custom_css.css index 9147825..6419471 100644 --- a/docs/css/custom_css.css +++ b/docs/css/custom_css.css @@ -7,3 +7,40 @@ table { display: table !important; border-spacing: 0px !important; } + +div.autodoc-docstring { + padding-left: 20px; + margin-bottom: 30px; + border-left: 5px solid rgba(230, 230, 230); +} + +div.autodoc-members { + padding-left: 20px; + margin-bottom: 15px; +} + +div.autodoc-signature *{ + /*display: none;*/ + all: initial !important; + /* + font-style: italic !important; + font-feature-settings: "kern","liga" !important; + font-family: var(--md-text-font-family,_),-apple-system,BlinkMacSystemFont,Helvetica,Arial,sans-serif !important; + */ + font-feature-settings: inherit !important; + font-family: inherit !important; + font-size: large !important; + font-weight: 600 !important; + /*color: #36464e !important;*/ + color: #7e54b9 !important; + /*background-color: #f5f5f5 !important;*/ +} +em.autodoc-param{ + font-style: italic !important; + font-weight: 500 !important; +} + +.autodoc-docstring{ + border-color: #977fb8 !important; + border- +} \ No newline at end of file diff --git a/docs/ecnqueue.md b/docs/ecnqueue.md index 9f329aa..26fb6ac 100644 --- a/docs/ecnqueue.md +++ b/docs/ecnqueue.md @@ -1,21 +1,18 @@ # ECNQueue documentation -## Item Class - -::: webqueue2_api.ECNQueue.Item +::: webqueue2_api.ECNQueue :docstring: -### Item functions +## Item Class ::: webqueue2_api.ECNQueue.Item + :docstring: + :private-members: :members: ## Queue Class ::: webqueue2_api.ECNQueue.Queue :docstring: - -### Queue Functions - -::: webqueue2_api.ECNQueue.Queue - :memebers: + :private-members: + :members: diff --git a/webqueue2_api/ECNQueue.py b/webqueue2_api/ECNQueue.py index 17d9c5a..4fbcd65 100644 --- a/webqueue2_api/ECNQueue.py +++ b/webqueue2_api/ECNQueue.py @@ -85,25 +85,31 @@ def isValidItemName(name: str) -> bool: class Item: """A single issue. - Example: - # Create an Item (ce100) - >>> item = Item("ce", 100) - - Attributes: - lastUpdated: An ISO 8601 formatted time string showing the last time the file was updated according to the filesystem. - headers: A list of dictionaries containing header keys and values. - content: A list of section dictionaries. - isLocked: A boolean showing whether or not a lockfile for the item is present. - userEmail: The email address of the person who this item is from. - userName: The real name of the person who this item is from. - userAlias: The Purdue career account alias of the person this item is from. - assignedTo: The Purdue career account alias of the person this item is assigned to - subject: The subject of the original message for this item. - status: The most recent status update for the item. - priority: The most recent priority for this item. - department: The most recent department for this item. - dateReceived: The date this item was created. - jsonData: A JSON serializable representation of the Item. + **Example:** + + ``` + # Create an Item (ce100) + >>> item = Item("ce", 100) + ``` + + **Attributes:** + + ``` + lastUpdated: An ISO 8601 formatted time string showing the last time the file was updated according to the filesystem. + headers: A list of dictionaries containing header keys and values. + content: A list of section dictionaries. + isLocked: A boolean showing whether or not a lockfile for the item is present. + userEmail: The email address of the person who this item is from. + userName: The real name of the person who this item is from. + userAlias: The Purdue career account alias of the person this item is from. + assignedTo: The Purdue career account alias of the person this item is assigned to + subject: The subject of the original message for this item. + status: The most recent status update for the item. + priority: The most recent priority for this item. + department: The most recent department for this item. + dateReceived: The date this item was created. + jsonData: A JSON serializable representation of the Item. + ``` """ def __init__(self, queue: str, number: int) -> None: @@ -155,11 +161,15 @@ def __init__(self, queue: str, number: int) -> None: def __getLastUpdated(self) -> str: """Returns last modified time of item reported by the filesystem in mm-dd-yy hh:mm am/pm format. - Example: - 07-23-20 10:34 AM + **Example:** + ``` + 07-23-20 10:34 AM + ``` - Returns: - str: last modified time of item reported by the filesystem in mm-dd-yy hh:mm am/pm format. + **Returns:** + ``` + str: last modified time of item reported by the filesystem in mm-dd-yy hh:mm am/pm format. + ``` """ # TODO: Simplify this code block by allowing __getFormattedDate to accept milliseconds since the epoch. unixTime = os.path.getmtime(self.__path) @@ -170,8 +180,10 @@ def __getLastUpdated(self) -> str: def __getRawItem(self) -> list: """Returns a list of all lines in the item file - Returns: - list: List of all the lines in the item file + **Returns:** + ``` + list: List of all the lines in the item file + ``` """ with open(self.__path, errors="replace") as file: return file.readlines() @@ -179,13 +191,18 @@ def __getRawItem(self) -> list: def __getHeaderBoundary(self) -> int: """Returns the 0 based line number where the Item headers stop. - Example: The header end would be on line 13 - 12: X-ECN-Queue-Original-URL: - 13: - 14: I need help. - - Returns: - int: line number where the Item headers end + **Example:** + ``` + The header end would be on line 13 + 12: X-ECN-Queue-Original-URL: + 13: + 14: I need help. + ``` + + **Returns:** + ``` + int: line number where the Item headers end + ``` """ for lineNumber, line in enumerate(self.__rawItem): if line == "\n": @@ -195,16 +212,20 @@ def __parseHeaders(self) -> list: """Returns a list containing dictionaries of header type and data. Removes queue prefixes and whitespace. - Examples: - "[ce] QStatus: Dont Delete\\nFrom: Justin Campbell \\n" - becomes - [ - {"QStatus": "Don't Delete"}, - {"From": "Justin Campbell "} - ] + **Examples:** + ``` + "[ce] QStatus: Dont Delete\\nFrom: Justin Campbell \\n" + becomes + [ + {"QStatus": "Don't Delete"}, + {"From": "Justin Campbell "} + ] + ``` - Returns: - list: Header dicts + **Returns:** + ``` + list: Header dicts + ``` """ headerString = "" @@ -413,25 +434,31 @@ def __parseSections(self) -> list: def __directoryParsing(self, directoryStartLine: int) -> dict: """Returns a dictionary with directory information - Example: - Name: Nestor Fabian Rodriguez Buitrago - Login: rodri563 - Computer: ce-205-38 (128.46.205.67) - Location: HAMP G230 - Email: rodri563@purdue.edu - Phone: 7654766893 - Office: HAMP G230 - UNIX Dir: /home/bridge/b/rodri563 - Zero Dir: U=\\bridge.ecn.purdue.edu\rodri563 - User ECNDB: http://eng.purdue.edu/jump/2e8399a - Host ECNDB: http://eng.purdue.edu/jump/2e83999 - Subject: Autocad installation - - Args: - directoryStartLine (int): line number within the item that the directory starts on - - Returns: - dict: dictionary that splits each line within the directory into a key and a value + **Example:** + + ``` + Name: Nestor Fabian Rodriguez Buitrago + Login: rodri563 + Computer: ce-205-38 (128.46.205.67) + Location: HAMP G230 + Email: rodri563@purdue.edu + Phone: 7654766893 + Office: HAMP G230 + UNIX Dir: /home/bridge/b/rodri563 + Zero Dir: U=\\\\bridge.ecn.purdue.edu\\rodri563 + User ECNDB: http://eng.purdue.edu/jump/2e8399a + Host ECNDB: http://eng.purdue.edu/jump/2e83999 + Subject: Autocad installation + ``` + + **Args:** + + `directoryStartLine (int)`: line number within the item that the directory starts on + + **Returns:** + ``` + dict: dictionary that splits each line within the directory into a key and a value + ``` """ directoryInformation = {"type": "directory_information"} @@ -525,22 +552,29 @@ def __directoryParsing(self, directoryStartLine: int) -> dict: def __assignmentParsing(self, contentStart: int) -> list: """Returns a list with assignment information dictionaries - Example: - Assigned-To: campb303 - Assigned-To-Updated-Time: Tue, 23 Jun 2020 13:27:00 EDT - Assigned-To-Updated-By: campb303 + **Example:** - Args: - contentStart (int): line number where the content starts + ``` + Assigned-To: campb303 + Assigned-To-Updated-Time: Tue, 23 Jun 2020 13:27:00 EDT + Assigned-To-Updated-By: campb303 + ``` - Returns: - list: [ - {"type": "assignment", - "datetime": datetime of the assignment, - "by": user who initiated the assignment, - "to": user who was assigned - }, - ] + **Args:** + + `contentStart (int)`: line number where the content starts + + **Returns:** + + ``` + list: [ + {"type": "assignment", + "datetime": datetime of the assignment, + "by": user who initiated the assignment, + "to": user who was assigned + }, + ] + ``` """ assignmentList = [] @@ -587,24 +621,28 @@ def __assignmentParsing(self, contentStart: int) -> list: def __initialMessageParsing(self, content: list) -> dict: """Returns a dictionary with initial message information - Example: - \n - Testtest\n - \n - - Args: - content (list): content of the initial message - - Returns: - dict: - "type": "initial_message", - "datetime": datetime the initial message was sent, - "from_name": from_name, - "from_email": user_email, - "to": [{email, name}], - "cc": [{email, name}], - "subject": initial message subject - "content": content of the initial message + **Example:** + ``` + \n + Testtest\n + \n + ``` + + **Args:** + `content (list)`: content of the initial message + + **Returns:** + ``` + dict: + "type": "initial_message", + "datetime": datetime the initial message was sent, + "from_name": from_name, + "from_email": user_email, + "to": [{email, name}], + "cc": [{email, name}], + "subject": initial message subject + "content": content of the initial message + ``` """ initialMessageDictionary = {} @@ -665,24 +703,27 @@ def __initialMessageParsing(self, content: list) -> dict: def __editParsing(self, content: list, lineNum: int) -> dict: """Returns a dictionary with edit information - Example: - *** Edited by: campb303 at: 06/23/20 13:27:56 ***\n - \n - This be an edit my boy\n - \n - \n - \n + **Example:** + ``` + \*\*\* Edited by: campb303 at: 06/23/20 13:27:56 \*\*\* + This be an edit my boy - Args: - content (list): content of an edit - lineNum (int): line number of an edit within an item - Returns: - dict: a dictionary with these keys, - "type": "edi", - "by": initiator of the edit, - "datetime": datetime of the edit, - "content": content of the edit + ``` + **Args:** + + `content (list)`: content of an edit + + `lineNum (int)`: line number of an edit within an item + + **Returns:** + ``` + dict: a dictionary with these keys: + "type": "edit", + "by": initiator of the edit, + "datetime": datetime of the edit, + "content": content of the edit + ``` """ # Edit Info dictionary @@ -724,25 +765,30 @@ def __editParsing(self, content: list, lineNum: int) -> dict: def __replyToParsing(self, content: list, lineNum: int) -> dict: """Returns a dictionary with reply to user information - Example: - *** Replied by: campb303 at: 06/23/20 13:28:18 ***\n - \n - This be a reply my son\n - \n - Justin\n - ECN\n - \n + **Example:** + ``` + \*\*\* Replied by: campb303 at: 06/23/20 13:28:18 \*\*\* - Args: - content (list): content of a reply to user - lineNum (int): line number of a reply to user in an item + This be a reply my son + + Justin + ECN + ``` - Returns: - dict: a dictionary with these keys, - "type": "reply_to_user", - "by": initiator of the reply to user, - "datetime": datetime of the reply to user, - "content": content of the reply to user + **Args:** + + `content (list)`: content of a reply to user + + `lineNum (int)`: line number of a reply to user in an item + + **Returns:** + ``` + dict: a dictionary with these keys, + "type": "reply_to_user", + "by": initiator of the reply to user, + "datetime": datetime of the reply to user, + "content": content of the reply to user + ``` """ replyInfo = {} @@ -781,20 +827,27 @@ def __replyToParsing(self, content: list, lineNum: int) -> dict: def __statusParsing(self, content: list, lineNum: int) -> dict: """Returns a dictionary with status information - Example: - *** Status updated by: campb303 at: 6/23/2020 13:26:55 ***\n - Dont Delete\n + **Example:** + ``` + \*\*\* Status updated by: campb303 at: 6/23/2020 13:26:55 \*\*\* + Dont Delete + \n + ``` - Args: - content (list): The content of a status update - lineNum (int): The line number of a status update in an item + **Args:** - Returns: - dict: a dictionary with these keys, - "type": "status", - "by": initiator of the status update, - "datetime": datetime of the status update, - "content": content of the status update + `content (list)`: The content of a status update + + `lineNum (int)`: The line number of a status update in an item + + **Returns:** + ``` + dict: a dictionary with these keys, + "type": "status", + "by": initiator of the status update, + "datetime": datetime of the status update, + "content": content of the status update + ``` """ statusInfo = {} @@ -836,41 +889,47 @@ def __statusParsing(self, content: list, lineNum: int) -> dict: def __userReplyParsing(self, replyContent: list, lineNumber: int) -> dict: """Returns a dictionary with user reply information - Example: - === Additional information supplied by user ===\n - \n - Subject: Re: Beepboop\n - From: Justin Campbell \n - Date: Tue, 23 Jun 2020 13:30:45 -0400\n - X-ECN-Queue-Original-Path: /home/pier/e/queue/Attachments/inbox/2020-06-23/212-original.txt\n - X-ECN-Queue-Original-URL: https://engineering.purdue.edu/webqueue/Attachments/inbox/2020-06-23/212-original.txt\n - \n - Huzzah!\n - \n - ===============================================\n - \n - Args: - replyContent (list): The entire section of a reply-from-user - lineNumber (int): The line number of the begining of a reply-from-user section within and item + **Example:** + ``` + === Additional information supplied by user === + + Subject: Re: Beepboop\n + From: Justin Campbell \n + Date: Tue, 23 Jun 2020 13:30:45 -0400\n + X-ECN-Queue-Original-Path: /home/pier/e/queue/Attachments/inbox/2020-06-23/212-original.txt\n + X-ECN-Queue-Original-URL: https://engineering.purdue.edu/webqueue/Attachments/inbox/2020-06-23/212-original.txt\n + + Huzzah! + + =============================================== + \n + ``` + **Args:** + + `replyContent (list)`: The entire section of a reply-from-user + + `lineNumber (int)`: The line number of the begining of a reply-from-user section within and item Returns: - dict: a dictionary with these keys, - "type": "reply_from_user", - "from_name": name of the user that sent the reply, - "from_email": email of the user that sent the reply, - "subject": subject of the reply, - "datetime": the datetime of the reply, - "cc": [ - {"name": name of the carbon copied recipient, - "email": email of the carbon copied recipient - }, - ] - "content": content of the reply - "headers": [ - {"type": headerType, - "content": content - }, - ] + ``` + dict: a dictionary with these keys, + "type": "reply_from_user", + "from_name": name of the user that sent the reply, + "from_email": email of the user that sent the reply, + "subject": subject of the reply, + "datetime": the datetime of the reply, + "cc": [ + {"name": name of the carbon copied recipient, + "email": email of the carbon copied recipient + }, + ] + "content": content of the reply + "headers": [ + {"type": headerType, + "content": content + }, + ] + ``` """ replyFromInfo = {} @@ -987,22 +1046,23 @@ def __userReplyParsing(self, replyContent: list, lineNumber: int) -> dict: def __getFormattedSectionContent(self, sectionContent: list) -> list: """Returns a list with message content that is stripped of unnecessary newlines and begining delimiters - Example: - *** Edited by: mph at: 02/21/20 10:27:16 ***\n - \n - Still need to rename machines - but the networking issue now seems to \n - be resolved via another ticket.\n - \n - \n - \n - \n - \n + **Example:** + ``` + \*\*\* Edited by: mph at: 02/21/20 10:27:16 \*\*\* + + Still need to rename machines - but the networking issue now seems to \n + be resolved via another ticket. + \n + ``` - Args: - sectionContent (list): The section content of a parsed section + **Args:** - Returns: - list: the section content of a parsed section without any delimiters and unnecessary newlines + `sectionContent (list)`: The section content of a parsed section + + **Returns:** + ``` + list: the section content of a parsed section without any delimiters and unnecessary newlines + ``` """ # Continually removes the first line of sectionContent if it is a newline or delimiter in each iteration while len(sectionContent) > 1: @@ -1037,22 +1097,29 @@ def __getFormattedSectionContent(self, sectionContent: list) -> list: def __errorParsing(self, line: str, lineNum: int, expectedSyntax: str) -> dict: """Returns a dictionary with error parse information when a line is malformed - Example: - "*** Status updated by: ewhile at: 5/7/2020 10:59:11 *** sharing between\n" + **Example:** + ``` + \*\*\* Status updated by: ewhile at: 5/7/2020 10:59:11 \*\*\* + ``` - Args: - line (str): line of that threw error - lineNum (int): line number in the item that threw error - expectedSyntax (str): a message stating the syntax the line should follow + **Args:** - Returns: - dict: a dictionary with these keys, - "type": "parse_error", - "datetime": time the error was encountered, - "file_path": path of the item with erroneos line, - "expected": expectedSyntax, - "got": line, - "line_num": lineNum + `line (str)`: line of that threw error + + `lineNum (int)`: line number in the item that threw error + + `expectedSyntax (str)`: a message stating the syntax the line should follow + + **Returns:** + ``` + dict: a dictionary with these keys, + "type": "parse_error", + "datetime": time the error was encountered, + "file_path": path of the item with erroneos line, + "expected": expectedSyntax, + "got": line, + "line_num": lineNum + ``` """ errorDictionary = {} @@ -1081,14 +1148,19 @@ def __errorParsing(self, line: str, lineNum: int, expectedSyntax: str) -> dict: def __getSortedSections(self, sectionsList: list) -> list: """Sorts the sections chronologically by datetime - Example: - [example] need to do + **Example:** + ``` + [example] need to do + ``` - Args: - sections (list): the list of sections to be sorted + **Args:** - Returns: - list: a list of sections sorted by datetime + `sections (list)`: the list of sections to be sorted + + **Returns:** + ``` + list: a list of sections sorted by datetime + ``` """ sectionsLength = len(sectionsList) sortedSections = [] @@ -1120,14 +1192,21 @@ def __getSortedSections(self, sectionsList: list) -> list: def __isLocked(self) -> Union[str, bool]: """Returns a string info about the lock if true and a bool False if false - Example: A file is locked - "CE 100 is locked by campb303 using qvi" + **Example:** + ``` + A file is locked + "CE 100 is locked by campb303 using qvi" + ``` - Example: a file is not locked - False + **Example:** + ``` + a file is not locked + False + ``` - Returns: - Union[str, bool]: String with info about lock if true, bool False if false + **Returns:** + + `Union[str, bool]`: String with info about lock if true, bool False if false """ lockFile = self.__path + ".lck" if os.path.exists(lockFile): @@ -1143,19 +1222,28 @@ def __getMostRecentHeaderByType(self, headerType: str) -> str: """Return the data of most recent header of the given type. If no header of that type exists, return an empty string. - Example: Requesting a Status header that does exist - __getMostRecentHeaderByType("Status") - becomes "Waiting for Reply" + **Example:** + ``` + Requesting a Status header that does exist + __getMostRecentHeaderByType("Status") + becomes "Waiting for Reply" + ``` - Example: Requesting a Status header that doesn't exist - __getMostRecentHeaderByType("Status") - becomes "" + **Example:** + ``` + Requesting a Status header that doesn't exist + __getMostRecentHeaderByType("Status") + becomes "" + ``` - Args: - headerType (str): Type of header to return. + **Args:** - Returns: - str: data of most recent header of the given type or empty string. + `headerType (str)`: Type of header to return. + + **Returns:** + ``` + str: data of most recent header of the given type or empty string. + ``` """ for header in self.headers: if header["type"] == headerType: @@ -1166,15 +1254,21 @@ def __parseFromData(self, data: str) -> str: """Parse From header and return requested data. Returns empty string if requested data is unavailable. - Examples: From data is "From: Campbell, Justin " - __parseFromData(data="userName") returns "Campbell, Justin" - __parseFromData(data="userEmail") returns "campb303@purdue.edu" + **Examples:** + ``` + From data is "From: Campbell, Justin " + __parseFromData(data="userName") returns "Campbell, Justin" + __parseFromData(data="userEmail") returns "campb303@purdue.edu" + ``` - Args: - data (str): The data desired; can be "userName" or "userEmail". + **Args:** - Returns: - str: userName, userEmail or empty string. + `data (str)`: The data desired; can be "userName" or "userEmail". + + **Returns:** + ``` + str: userName, userEmail or empty string. + ``` """ fromHeader = self.__getMostRecentHeaderByType("From") userName, userEmail = email.utils.parseaddr(fromHeader) @@ -1191,14 +1285,22 @@ def __getUserAlias(self) -> str: """Returns user's Career Account alias if present. If Career Account alias isn't present, returns empty string. - Example: Email from campb303@purdue.edu - userAlias = "campb303" - - Example: Email from spam@spammer.net - userAlias = "" - - Returns: - str: User's Career Account alias if present or empty string + **Example:** + ``` + Email from campb303@purdue.edu + userAlias = "campb303" + ``` + + **Example:** + ``` + Email from spam@spammer.net + userAlias = "" + ``` + + **Returns:** + ``` + str: User's Career Account alias if present or empty string + ``` """ @@ -1220,8 +1322,10 @@ def __getFormattedDate(self, date: str) -> str: Returns empty string if the string argument passed to the function is not a datetime. See: https://en.wikipedia.org/wiki/ISO_8601 - Returns: - str: Properly formatted date/time recieved or empty string. + **Returns:** + ``` + str: Properly formatted date/time recieved or empty string. + ``` """ try: # This date is never meant to be used. The default attribute is just to set timezone. @@ -1237,8 +1341,10 @@ def __getFormattedDate(self, date: str) -> str: def toJson(self) -> dict: """Returns a JSON safe representation of the item. - Returns: - dict: JSON safe representation of the item. + **Returns:** + ``` + dict: JSON safe representation of the item. + ``` """ return self.jsonData @@ -1249,14 +1355,20 @@ def __repr__(self) -> str: class Queue: """A collection of items. - Example: - # Create a queue (ce) - >>> queue = Queue("ce") + **Example:** + + ``` + # Create a queue (ce) + >>> queue = Queue("ce") + ``` + + **Attributes:** - Attributes: - name: The name of the queue. - items: A list of Items in the queue. - jsonData: A JSON serializable representation of the Queue. + ``` + name: The name of the queue. + items: A list of Items in the queue. + jsonData: A JSON serializable representation of the Queue. + ``` """ def __init__(self, name: str) -> None: @@ -1272,8 +1384,10 @@ def __init__(self, name: str) -> None: def __getItems(self) -> list: """Returns a list of items for this Queue - Returns: - list: a list of items for this Queue + **Returns:** + ``` + list: a list of items for this Queue + ``` """ items = [] @@ -1293,8 +1407,10 @@ def toJson(self) -> dict: The JSON representation of every item in the Queue is added to the Queue's JSON data then the Queue's JSON data is returned. - Returns: - dict: JSON safe representation of the Queue + **Returns:** + ``` + dict: JSON safe representation of the Queue + ``` """ items = [] for item in self.items: @@ -1312,11 +1428,15 @@ def __repr__(self) -> str: def getValidQueues() -> list: """Returns a list of queues on the filesystem excluding ignored queues. - Example: - ["bidc", "me", "ce"] + **Example:** + ``` + ["bidc", "me", "ce"] + ``` - Returns: - list: Valid queues + **Returns:** + ``` + list: Valid queues + ``` """ queues = [] @@ -1333,20 +1453,23 @@ def getValidQueues() -> list: def getQueueCounts() -> list: """Returns a list of dictionaries with the number of items in each queue. - Example: - [ - { - name: "me", - number_of_items: 42 - }, - { - name: "bidc", - number_of_items: 3 - } - ] - - Returns: - list: Dictionaries with the number of items in each queue. + **Example:** + ``` + [ + { + name: "me", + number_of_items: 42 + }, + { + name: "bidc", + number_of_items: 3 + } + ] + ``` + **Returns:** + ``` + list: Dictionaries with the number of items in each queue. + ``` """ queueInfo = [] for queue in getValidQueues(): @@ -1363,8 +1486,10 @@ def getQueueCounts() -> list: def loadQueues() -> list: """Return a list of Queues for each queue. - Returns: - list: list of Queues for each queue. + **Returns:** + ``` + list: list of Queues for each queue. + ``` """ queues = [] From 4838cac0375d30a4b167739179b0385866938aca Mon Sep 17 00:00:00 2001 From: benne238 Date: Mon, 29 Mar 2021 08:36:49 -0400 Subject: [PATCH 05/35] fix for .autodoc-docstring css --- docs/css/custom_css.css | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/css/custom_css.css b/docs/css/custom_css.css index 6419471..5f6e922 100644 --- a/docs/css/custom_css.css +++ b/docs/css/custom_css.css @@ -42,5 +42,4 @@ em.autodoc-param{ .autodoc-docstring{ border-color: #977fb8 !important; - border- } \ No newline at end of file From cf7ebff585a05385ea6a86d390312677b57032d5 Mon Sep 17 00:00:00 2001 From: benne238 Date: Mon, 29 Mar 2021 13:19:30 -0400 Subject: [PATCH 06/35] removed mentions of :private-memebers: from markdown files as autodoc does not support this yet --- docs/ecnqueue.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/ecnqueue.md b/docs/ecnqueue.md index 26fb6ac..7d44c8a 100644 --- a/docs/ecnqueue.md +++ b/docs/ecnqueue.md @@ -7,12 +7,10 @@ ::: webqueue2_api.ECNQueue.Item :docstring: - :private-members: :members: ## Queue Class ::: webqueue2_api.ECNQueue.Queue :docstring: - :private-members: :members: From f3b9d676ac8c23177fa1016bd82003d9c2104dd6 Mon Sep 17 00:00:00 2001 From: benne238 Date: Mon, 29 Mar 2021 14:43:52 -0400 Subject: [PATCH 07/35] added additional information for the overview --- docs/webqueue2 backend overview.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/webqueue2 backend overview.md b/docs/webqueue2 backend overview.md index 2620d60..9c128d3 100644 --- a/docs/webqueue2 backend overview.md +++ b/docs/webqueue2 backend overview.md @@ -9,4 +9,9 @@ In order to function, the backend of Webqueue2 relies primarily on two scripts, ### ECNQueue.py The `ECNQueue.py` script does all of the data and information parsing. -Items are currently stored in plain text within text files and all updates to those items are documented directly into those textfiles via the `qcli`. The `ECNQueue.py` script parses these text files and stores all the information regarding the item into a custom `Item` object. \ No newline at end of file +Items are currently stored in plain text within text files and all updates to those items are documented directly into those textfiles via the `qcli`. The `ECNQueue.py` script parses these text files and stores all the information regarding the item into a custom `Item` object. + +### api.py +The `api.py` script does all of the interaction between the front end and the `ECNQueue.py` script. + +The front end makes requests, which are then routed to the `api.py` script, which are translated to functions within the `ECNQueue.py`. The json that the `ECNQueue.py` script returns is then returned to the `api.py` script which then routes the json to the frontend. \ No newline at end of file From fdf4aebc61c5422d21a26eb7c990c157b376112d Mon Sep 17 00:00:00 2001 From: benne238 Date: Mon, 29 Mar 2021 15:08:34 -0400 Subject: [PATCH 08/35] update api.py docstrings --- webqueue2_api/api.py | 152 +++++++++++++++++++++++++------------------ 1 file changed, 87 insertions(+), 65 deletions(-) diff --git a/webqueue2_api/api.py b/webqueue2_api/api.py index 7fcefa4..f32a90d 100644 --- a/webqueue2_api/api.py +++ b/webqueue2_api/api.py @@ -109,20 +109,24 @@ class Login(Resource): def post(self) -> tuple: """Validates username/password and returns both access and refresh tokens. - Return Codes: - 200 (OK): On success. - 401 (Unauthroized): When username or password are incorrect. - 422 (Unprocessable Entitiy): When the username or password can't be parsed. - - Example: - curl -X POST - -H "Content-Type: application/json" - -d '{"username": "bob", "password": "super_secret"}' - - { "access_token": fjr09hfp09h932jp9ruj3.3r8ihf8h0w8hr08ifhj804h8i.8h48ith08ity409hip0t4 } - - Returns: - tuple: Response containing tokens and HTTP response code. + **Return Codes:** + ``` + 200 (OK): On success. + 401 (Unauthroized): When username or password are incorrect. + 422 (Unprocessable Entitiy): When the username or password can't be parsed. + ``` + **Example:** + ``` + curl -X POST + -H "Content-Type: application/json" + -d '{"username": "bob", "password": "super_secret"}' + + { "access_token": fjr09hfp09h932jp9ruj3.3r8ihf8h0w8hr08ifhj804h8i.8h48ith08ity409hip0t4 } + ``` + **Returns:** + ``` + tuple: Response containing tokens and HTTP response code. + ``` """ if not request.is_json: return ({ "message": "JSON missing from request body"}, 422) @@ -162,34 +166,41 @@ class Item(Resource): def get(self, queue: str, number: int) -> tuple: """Returns the JSON representation of the item requested. - Return Codes: - 200 (OK): On success. - - Example: - /api/ce/100 returns: - { - "lastUpdated": "07-23-20 10:11 PM", - "headers": [...], - "content": [...], - "isLocked": "ce 100 is locked by knewell using qvi", - "userEmail": "campb303@purdue.edu", - "userName": "Justin Campbell", - "userAlias": "campb303", - "assignedTo": "campb303", - "subject": "Beepboop", - "status": "Dont Delete", - "priority": "", - "deparment": "", - "building": "", - "dateReceived": "Tue, 23 Jun 2020 13:25:51 -0400" - } - - Args: - queue (str): The queue of the item requested. - item (int): The number of the item requested. - - Returns: - tuple: Item as JSON and HTTP response code. + **Return Codes:** + ``` + 200 (OK): On success. + ``` + + **Example:** + ``` + /api/ce/100 returns: + { + "lastUpdated": "07-23-20 10:11 PM", + "headers": [...], + "content": [...], + "isLocked": "ce 100 is locked by knewell using qvi", + "userEmail": "campb303@purdue.edu", + "userName": "Justin Campbell", + "userAlias": "campb303", + "assignedTo": "campb303", + "subject": "Beepboop", + "status": "Dont Delete", + "priority": "", + "deparment": "", + "building": "", + "dateReceived": "Tue, 23 Jun 2020 13:25:51 -0400" + } + ``` + **Args:** + ``` + queue (str): The queue of the item requested. + item (int): The number of the item requested. + ``` + + **Returns:** + ``` + tuple: Item as JSON and HTTP response code. + ``` """ return (ECNQueue.Item(queue, number).toJson(), 200) @@ -198,14 +209,20 @@ class Queue(Resource): def get(self, queues: str) -> tuple: """Returns the JSON representation of the queue requested. - Return Codes: - 200 (OK): On success. + **Return Codes:** + ``` + 200 (OK): On success. + ``` - Args: - queues (str): Plus (+) deliminited list of queues. + **Args:** + ``` + queues (str): Plus (+) deliminited list of queues. + ``` - Returns: - tuple: Queues as JSON and HTTP response code. + **Returns:** + ``` + tuple: Queues as JSON and HTTP response code. + ``` """ queues_requested = queues.split("+") @@ -220,23 +237,28 @@ class QueueList(Resource): def get(self) -> tuple: """Returns a list of dictionaries with the number of items in each queue. - Return Codes: - 200 (OK): On success. - - Example: - [ - { - name: "me", - number_of_items: 42 - }, - { - name: "bidc", - number_of_items: 3 - } - ] - - Returns: - tuple: Queues and item counts as JSON and HTTP response code. + **Return Codes:** + ``` + 200 (OK): On success. + ``` + + **Example:** + ``` + [ + { + name: "me", + number_of_items: 42 + }, + { + name: "bidc", + number_of_items: 3 + } + ] + ``` + **Returns:** + ``` + tuple: Queues and item counts as JSON and HTTP response code. + ``` """ return (ECNQueue.getQueueCounts(), 200) From 1fe26c68165037188323c045be72263da351dc13 Mon Sep 17 00:00:00 2001 From: Justin Campbell Date: Thu, 1 Apr 2021 11:46:28 -0400 Subject: [PATCH 09/35] Create get_access_token snippet --- docs/api/get_access_token.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 docs/api/get_access_token.js diff --git a/docs/api/get_access_token.js b/docs/api/get_access_token.js new file mode 100644 index 0000000..d4ae59d --- /dev/null +++ b/docs/api/get_access_token.js @@ -0,0 +1,21 @@ +const accessToken = (async _ => { + const loginInit = { + method: "POST", + headers: {'Content-Type': 'application/json'}, + body: JSON.stringify({ "username": USERNAME, "password": PASSWORD}) + }; + + let loginResponse = await fetch("https://engineering.purdue.edu/webqueue/webqueue2/build/api/login", loginInit); + let data = await loginResponse.json(); + + if (data === null){ + return false; + } + + if (!loginResponse.ok){ + console.error(`Login failed. Got code ${loginResponse.status} (${loginResponse.statusText})`); + return false; + } + + return data.access_token || false; + })(); \ No newline at end of file From f52d74f5988ea7b0aab35eedcdd4b265c3dbd8ab Mon Sep 17 00:00:00 2001 From: Justin Campbell Date: Thu, 1 Apr 2021 12:15:53 -0400 Subject: [PATCH 10/35] Replace token with include --- docs/api/Authentication.md | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/docs/api/Authentication.md b/docs/api/Authentication.md index 3c54581..7097641 100644 --- a/docs/api/Authentication.md +++ b/docs/api/Authentication.md @@ -14,27 +14,7 @@ All API calls require an access token. You can get an access token by making a P === "fetch" ```javascript - const accessToken = (async _ => { - const loginInit = { - method: "POST", - headers: {'Content-Type': 'application/json'}, - body: JSON.stringify({ "username": USERNAME, "password": PASSWORD}) - }; - - let loginResponse = await fetch("{{ production_url }}/api/login", loginInit); - let data = await loginResponse.json(); - - if (data === null){ - return false; - } - - if (!loginResponse.ok){ - console.error(`Login failed. Got code ${loginResponse.status} (${loginResponse.statusText})`); - return false; - } - - return data.access_token || false; - })(); + {% include 'api/get_access_token.js' %} ``` === "cURL" @@ -144,7 +124,7 @@ To refresh your access token, make a POST request to the `/api/tokens/refresh` e === "fetch" ```javascript const newAccessToken = (async _ => { - const csrf_refresh_token = some_func_to_get_csrf_token(); + const csrf_refresh_token = some_func_to_get_csrf_token_cookie(); const refreshInit = { method: "POST", From 858dd3b16084d8be8c5166167c5a61016d16e6c8 Mon Sep 17 00:00:00 2001 From: Justin Campbell Date: Thu, 1 Apr 2021 21:37:03 -0400 Subject: [PATCH 11/35] Remove cURL examples, finish basic usage examples --- docs/api/Getting Started.md | 51 ++++++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 18 deletions(-) diff --git a/docs/api/Getting Started.md b/docs/api/Getting Started.md index e6b5fea..e43f0fe 100644 --- a/docs/api/Getting Started.md +++ b/docs/api/Getting Started.md @@ -2,26 +2,41 @@ The webqueue2 API is organized around [REST](https://en.wikipedia.org/wiki/Representational_state_transfer). The API has resource oriented URLs, accepts and returns JSON encoded request bodies, can be modified via the query string and uses standard HTTP response codes and verbs. +You can use the webqueue2 API hosted at `{{ production_url }}/api` or [install it on your own machine](Installation.md). + ## Basic Usage -!!! example "Get the number of Items in a Queue" - === "fetch" - ```javascript - ()(); - ``` +!!! example "Get the first item in CE queue." + ```javascript + let access_token = "{{ example_access_token }}"; + let queue = "ce"; - === "cURL" - ```bash - curl -K - ``` + fetch( + `https://engineering.purdue.edu/webqueue/webqueue2/build/api/data/${queue}`, + { headers: {"Authorization":`Bearer ${access_token}` }} + ) + .then( resp => resp.json() ) + .then( data => console.log( data[0].items[0] )); + ``` + ```js + // Expected Output + { queue: "ce", number: 17, lastUpdated: "2021-03-29T17:12:00-0400" ... } + ``` -!!! example "Get the subject of an Item" - === "fetch" - ```javascript - console.log - ``` +!!! example "Get the subject of an CE 1." + ```javascript + let access_token = "{{ example_access_token }}"; + let queue = "ce"; + let item_number = 1; - === "cURL" - ```bash - curl -K - ``` \ No newline at end of file + fetch( + `https://engineering.purdue.edu/webqueue/webqueue2/build/api/data/${queue}/${item_number}`, + { headers: {"Authorization":`Bearer ${access_token}` }} + ) + .then( resp => resp.json() ) + .then( data => console.log( data.subject )); + ``` + ```js + // Expected Output + "Linux Server Purchase" + ``` \ No newline at end of file From d5f573d3905e9b00b30eb0b945e163c16660eb33 Mon Sep 17 00:00:00 2001 From: Justin Campbell Date: Thu, 1 Apr 2021 22:39:16 -0400 Subject: [PATCH 12/35] Remove cURL examples, simplify javascript examples --- docs/api/Authentication.md | 177 ++++++++----------------------------- 1 file changed, 38 insertions(+), 139 deletions(-) diff --git a/docs/api/Authentication.md b/docs/api/Authentication.md index 7097641..15a097d 100644 --- a/docs/api/Authentication.md +++ b/docs/api/Authentication.md @@ -12,105 +12,41 @@ All API calls require an access token. You can get an access token by making a P - `00000227-ECNStuds` - `00000227-ECN-webqueue-misc` -=== "fetch" - ```javascript - {% include 'api/get_access_token.js' %} - ``` - -=== "cURL" - !!! warning - It is **strongly** recomended to store and retrieve your login credentials in a [cURL config file](https://everything.curl.dev/cmdline/configfile) that only your user can read to avoid exposing your credentials to your shell history or the host process table. - - Create a cURL config file named `wq2_login.config`: - ```bash - nano ~/wq_login.config - ``` - - Add the cURL options: - ```python - # ~/wq_login.config - request = POST - header = "Content-Type: application/json" - data = {"username":"USERNAME","password":"PASSWORD"} - url = "{{ production_url }}/api/login" - # Save cookies for future API calls - cookies = "wq_cookies" - ``` - - Restrict read permissions to your user: - ```bash - chmod 700 ~/wq_login.config - ``` +### Example +!!! example "Get an access token." - Run cURL using your new config file: - ```bash - curl -K ~/wq_login.config - ``` + ```js + {% include 'api/get_access_token.js' %} ``` - # Expected Output: - {"access_token": "{{ example_access_token }}"} + ```js + // Expected Output + "{{ example_access_token }}" ``` - ??? tip "Tip for Parsing Tokens in Bash" - You can parse the access token using Python like this: - ```bash - curl -K ~/wq_login.config | \ - python3 -c "import sys, json; print(json.load(sys.stdin)['access_token'])" - ``` - ## Making Calls With Access Token To interact with the API, add an `Authorization` header to your request with a value of `Bearer TOKEN` where `TOKEN` is your access token. -Example: Get item `ce100` -=== "fetch" - ```javascript - const ce100 = (async _ => { - const loginInit = { - method: "GET", - headers: {'Authentication': 'Bearer {{ example_access_token }}'}, - }; - - let apiResponse = await fetch("{{ production_url }}/api/data/ce/100", loginInit); - let data = await apiResponse.json(); - - if (data === null){ - return false; - } +### Example: +!!! example "Get item `ce100`" + ```js + let access_token = "{{ example_access_token }}"; + let queue = "ce"; + let item_number = 100; - if (!apiResponse.ok){ - console.error(`Fetching item ce100 failed. Got code ${apiResponse.status} (${apiResponse.statusText})`); - return false; - } - - return data || false; - })(); + fetch( + `https://engineering.purdue.edu/webqueue/webqueue2/build/api/data/${queue}/${item_number}`, + { headers: {"Authorization":`Bearer ${access_token}` }} + ) + .then( resp => resp.json() ) + .then( data => console.log( data )); ``` - -=== "cURL" - Create a cURL config file named `wq_get_ce100.config`: - ```bash - nano ~/wq_get_ce100.config - ``` - - Set cURL options - ```python - # ~/wq_get_ce100.config - request = GET - header = "Authorization: Bearer {{ example_access_token }}" - url = "{{ production_url }}/api/data/ce/100" - ``` - - Run cURL using your new config file: - ```bash - curl -K ~/wq_get_ce100.config - ``` - ``` - # Expected Output: - { 'assignedTo': 'campb303', 'building': '', 'content': [...], 'dateReceived': '2020-06-23T13:25:51-0400', 'department': '', 'headers': [...], 'isLocked': 'ce 100 is locked by knewell using qvi', 'lastUpdated': '2020-12-01T19:53:00-0500', 'number': 100, 'priority': '', 'queue': 'ce', 'status': 'Dont Delete', 'subject': 'Beepboop', 'userAlias': 'campb303', 'userEmail': 'campb303@purdue.edu', 'userName': 'Justin Campbell' } + ```js + // Expected Output + {queue: "ce", number: 100, lastUpdated: "2021-03-11T07:24:00-0500" ... } ``` ## Refreshing Access Tokens -By default, access tokens expire 15 minutes after being issued and need refreshed. During login, you'll receive two cookies: +When you login, you'll receive an access token that expires 15 minutes after creation as well as two cookies needed to get a new access token: Name | Value | Path | Expiration | SameSite -- | -- | -- | -- | -- @@ -121,60 +57,23 @@ The `refresh_token_cookie` is used to generate a new access token and will be se To refresh your access token, make a POST request to the `/api/tokens/refresh` endpoint with the value of the `csrf_refresh_token` cookies inside a `X-CSRF-TOKEN` header: -=== "fetch" - ```javascript - const newAccessToken = (async _ => { - const csrf_refresh_token = some_func_to_get_csrf_token_cookie(); +### Example +!!! example "Get a new refresh token." + ```js + // Get this value from your cookies. + const csrf_refresh_token = "{{ example_csrf_token }}" - const refreshInit = { + fetch( + `{{ production_url }}/api/tokens/refresh`, + { method: "POST", - headers: {'X-CSRF-TOKEN': csrf_refresh_token}, - }; - - let refreshResponse = await fetch(`{{ production_url }}/api/tokens/refresh`, refreshInit); - let data = await refreshResponse.json(); - - if (data === null){ - return false; + headers: {'X-CSRF-TOKEN': csrf_refresh_token} } - if (!refreshResponse.ok){ - console.error(`Refresh failed. Got code ${refreshResponse.status} (${refreshResponse.statusText})`); - return false; - } - - return data.access_token || false; - })(); + ) + .then( resp => resp.json() ) + .then( data => console.log( data.access_token )); ``` - -=== "cURL" - Create a cURL config file named `wq_refresh.config`: - ```bash - nano ~/wq_refresh.config - ``` - - Set cURL options - ```python - # ~/wq_refresh.config - request = POST - header = "X-CSRF-TOKEN: {{ example_csrf_token }}" - url = "{{ production_url }}/api/tokens/refresh" - # Pull cookies from login. - cookie-jar = "wq_cookies" - ``` - - Run cURL using your new config file: - ```bash - curl -K ~/wq_refresh.config - ``` - ``` - # Expected Output: - {"access_token": "{{ example_access_token }}"} - ``` - - ??? tip "Tip for Parsing Tokens in Bash" - You can parse the access token using Python like this: - ```bash - curl -K ~/wq_login.config | \ - python3 -c "import sys, json; print(json.load(sys.stdin)['access_token'])" - ``` + ```js + // Expected Output + {{ example_access_token }} ``` \ No newline at end of file From 28ad8a18f87ff11d9cd2d915e7ed6e9482024457 Mon Sep 17 00:00:00 2001 From: Justin Campbell Date: Thu, 1 Apr 2021 22:39:41 -0400 Subject: [PATCH 13/35] Simplify examples, reference mkdocs variables --- docs/api/get_access_token.js | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/docs/api/get_access_token.js b/docs/api/get_access_token.js index d4ae59d..c3b5929 100644 --- a/docs/api/get_access_token.js +++ b/docs/api/get_access_token.js @@ -1,21 +1,10 @@ -const accessToken = (async _ => { - const loginInit = { +fetch( + "{{ production_url }}/api/login", + { method: "POST", headers: {'Content-Type': 'application/json'}, body: JSON.stringify({ "username": USERNAME, "password": PASSWORD}) - }; - - let loginResponse = await fetch("https://engineering.purdue.edu/webqueue/webqueue2/build/api/login", loginInit); - let data = await loginResponse.json(); - - if (data === null){ - return false; } - - if (!loginResponse.ok){ - console.error(`Login failed. Got code ${loginResponse.status} (${loginResponse.statusText})`); - return false; - } - - return data.access_token || false; - })(); \ No newline at end of file + ) + .then( resp => resp.json() ) + .then( data => console.log( data.access_token )) \ No newline at end of file From 3d6f94011ecaca0a00d47a816d580ba8f45829dd Mon Sep 17 00:00:00 2001 From: Justin Campbell Date: Fri, 2 Apr 2021 10:39:58 -0400 Subject: [PATCH 14/35] Add API section to table of contents --- docs/awesome-pages.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/awesome-pages.yaml b/docs/awesome-pages.yaml index e502d65..2672f54 100644 --- a/docs/awesome-pages.yaml +++ b/docs/awesome-pages.yaml @@ -1,4 +1,5 @@ # YAML Configuration for Awesome Pages mkdocs Plugin # See: https://github.com/lukasgeiter/mkdocs-awesome-pages-plugin nav: + - API: api - ... \ No newline at end of file From f4b0b89dcbfb2d86c30994da498a69852105183a Mon Sep 17 00:00:00 2001 From: Justin Campbell Date: Fri, 2 Apr 2021 10:47:51 -0400 Subject: [PATCH 15/35] Remove versioning TODO --- mkdocs.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/mkdocs.yml b/mkdocs.yml index 37596d7..d1623b6 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -35,9 +35,6 @@ markdown_extensions: # See: https://squidfunk.github.io/mkdocs-material/setup/changing-the-colors/ ################################################################################ -# TODO: Implement versioning -# See: https://squidfunk.github.io/mkdocs-material/setup/setting-up-versioning/#versioning - theme: name: material palette: From 72c0b8bb5c8a46ba2e8cd4db0c119429a555dccb Mon Sep 17 00:00:00 2001 From: Justin Campbell Date: Fri, 2 Apr 2021 10:48:33 -0400 Subject: [PATCH 16/35] Update GitHub link --- mkdocs.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mkdocs.yml b/mkdocs.yml index d1623b6..a9fc06e 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -54,8 +54,8 @@ extra: link: https://purdueecn.slack.com/archives/C019K7PSPNW name: webqueue2 on Slack - icon: fontawesome/brands/github - link: https://github.itap.purdue.edu/ECN/webqueue2 - name: webqueue2 on GitHub + link: https://github.itap.purdue.edu/ECN/webqueue2-api + name: webqueue2-API on GitHub production_url: "https://engineering.purdue.edu/webqueue/webqueue2/build" example_access_token: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE2MTY1NTIyMDIsIm5iZiI6MTYxNjU1MjIwMiwianRpIjoiZDgyNGM1MWItM2JmNy00ZDUzLWE0YTgtY2VhZWQ5ZmVjNGYzIiwiZXhwIjoxNjE2NTUzMTAyLCJzdWIiOiJjYW1wYjMwMyIsImZyZXNoIjpmYWxzZSwidHlwZSI6ImFjY2VzcyIsImNzcmYiOiI1Yjk5NWQ5OS05YjIzLTQyMjYtYTc0OC1lMmQ5OTA4MDkzOTQifQ.6z7EReDfhPkBkuAMHEvDuMDV4wVbqrWSjQXdRyv_5hE" example_csrf_token: "7b7c1ea8-f6bb-4204-99af-cd4124a69d89" From eea653ca273caf14965e32804ef37b33636c5483 Mon Sep 17 00:00:00 2001 From: Justin Campbell Date: Fri, 2 Apr 2021 10:49:14 -0400 Subject: [PATCH 17/35] Add comment for variables --- mkdocs.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/mkdocs.yml b/mkdocs.yml index a9fc06e..090fdf5 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -56,6 +56,7 @@ extra: - icon: fontawesome/brands/github link: https://github.itap.purdue.edu/ECN/webqueue2-api name: webqueue2-API on GitHub + # Variables for Macros production_url: "https://engineering.purdue.edu/webqueue/webqueue2/build" example_access_token: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE2MTY1NTIyMDIsIm5iZiI6MTYxNjU1MjIwMiwianRpIjoiZDgyNGM1MWItM2JmNy00ZDUzLWE0YTgtY2VhZWQ5ZmVjNGYzIiwiZXhwIjoxNjE2NTUzMTAyLCJzdWIiOiJjYW1wYjMwMyIsImZyZXNoIjpmYWxzZSwidHlwZSI6ImFjY2VzcyIsImNzcmYiOiI1Yjk5NWQ5OS05YjIzLTQyMjYtYTc0OC1lMmQ5OTA4MDkzOTQifQ.6z7EReDfhPkBkuAMHEvDuMDV4wVbqrWSjQXdRyv_5hE" example_csrf_token: "7b7c1ea8-f6bb-4204-99af-cd4124a69d89" From 57452f9d958b45167a973ad154c85c653d2bd5e7 Mon Sep 17 00:00:00 2001 From: Justin Campbell Date: Fri, 2 Apr 2021 11:05:49 -0400 Subject: [PATCH 18/35] Remove unnecessary file --- docs/index.md | 17 ----------------- docs/webqueue2 backend overview.md | 17 ----------------- 2 files changed, 34 deletions(-) delete mode 100644 docs/index.md delete mode 100644 docs/webqueue2 backend overview.md diff --git a/docs/index.md b/docs/index.md deleted file mode 100644 index 000ea34..0000000 --- a/docs/index.md +++ /dev/null @@ -1,17 +0,0 @@ -# Welcome to MkDocs - -For full documentation visit [mkdocs.org](https://www.mkdocs.org). - -## Commands - -* `mkdocs new [dir-name]` - Create a new project. -* `mkdocs serve` - Start the live-reloading docs server. -* `mkdocs build` - Build the documentation site. -* `mkdocs -h` - Print help message and exit. - -## Project layout - - mkdocs.yml # The configuration file. - docs/ - index.md # The documentation homepage. - ... # Other markdown pages, images and other files. diff --git a/docs/webqueue2 backend overview.md b/docs/webqueue2 backend overview.md deleted file mode 100644 index 9c128d3..0000000 --- a/docs/webqueue2 backend overview.md +++ /dev/null @@ -1,17 +0,0 @@ -# *(draft)* Webqueue2 backend overview - -!!! note - *This document should be renamed to `index.md` to make it the default landing page. The current index.md file contains information for mkdocs that maybe useful later* - -## Overview -In order to function, the backend of Webqueue2 relies primarily on two scripts, the `ECNQueue.py` script, and the `api.py` script. These two scripts work in conjuction with eachother inorder to read, parse, and transfer item and queue information created by the `qcli` to the frontend. - -### ECNQueue.py -The `ECNQueue.py` script does all of the data and information parsing. - -Items are currently stored in plain text within text files and all updates to those items are documented directly into those textfiles via the `qcli`. The `ECNQueue.py` script parses these text files and stores all the information regarding the item into a custom `Item` object. - -### api.py -The `api.py` script does all of the interaction between the front end and the `ECNQueue.py` script. - -The front end makes requests, which are then routed to the `api.py` script, which are translated to functions within the `ECNQueue.py`. The json that the `ECNQueue.py` script returns is then returned to the `api.py` script which then routes the json to the frontend. \ No newline at end of file From e3d40b5183018e7747207cedb087dc83709c3d33 Mon Sep 17 00:00:00 2001 From: Justin Campbell Date: Fri, 2 Apr 2021 14:32:26 -0400 Subject: [PATCH 19/35] Minor wording changes --- docs/api/Authentication.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/api/Authentication.md b/docs/api/Authentication.md index 15a097d..8d1b613 100644 --- a/docs/api/Authentication.md +++ b/docs/api/Authentication.md @@ -27,7 +27,7 @@ All API calls require an access token. You can get an access token by making a P To interact with the API, add an `Authorization` header to your request with a value of `Bearer TOKEN` where `TOKEN` is your access token. ### Example: -!!! example "Get item `ce100`" +!!! example "Get item CE 100." ```js let access_token = "{{ example_access_token }}"; let queue = "ce"; @@ -46,14 +46,14 @@ To interact with the API, add an `Authorization` header to your request with a v ``` ## Refreshing Access Tokens -When you login, you'll receive an access token that expires 15 minutes after creation as well as two cookies needed to get a new access token: +When you login, you'll receive an access token that expires 15 minutes after creation as well as two cookies needed to get a new access token. Those cookies are: Name | Value | Path | Expiration | SameSite -- | -- | -- | -- | -- `refresh_token_cookie` | Your refresh token. | `/api/tokens/refresh` | 30 Days | Yes `csrf_refresh_token` | Additional verification data. (e.g. `{{ example_csrf_token }}`) | `/` | Session | Yes -The `refresh_token_cookie` is used to generate a new access token and will be sent back to the server with every request automatically. The `csrf_refresh_token` is used to verify the `refresh_token_cookie` and needs sent back as an `X-CSRF-TOKEN` header. +The `refresh_token_cookie` is used to generate a new access token and will be sent back to the server with every request automatically. It expires 30 days after login. The `csrf_refresh_token` is used to verify the `refresh_token_cookie` and needs sent back as an `X-CSRF-TOKEN` header. To refresh your access token, make a POST request to the `/api/tokens/refresh` endpoint with the value of the `csrf_refresh_token` cookies inside a `X-CSRF-TOKEN` header: From 034bb2d87181f70116155664c2096827de4d1329 Mon Sep 17 00:00:00 2001 From: Justin Campbell Date: Fri, 2 Apr 2021 14:32:39 -0400 Subject: [PATCH 20/35] Create new index file --- docs/awesome-pages.yaml | 1 + docs/index.md | 0 2 files changed, 1 insertion(+) create mode 100644 docs/index.md diff --git a/docs/awesome-pages.yaml b/docs/awesome-pages.yaml index 2672f54..1cacee8 100644 --- a/docs/awesome-pages.yaml +++ b/docs/awesome-pages.yaml @@ -1,5 +1,6 @@ # YAML Configuration for Awesome Pages mkdocs Plugin # See: https://github.com/lukasgeiter/mkdocs-awesome-pages-plugin nav: + - index.md - API: api - ... \ No newline at end of file diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..e69de29 From 5fdecb58f1cce985c4980f092cf3fc13c3ce1395 Mon Sep 17 00:00:00 2001 From: Justin Campbell Date: Fri, 2 Apr 2021 17:15:51 -0400 Subject: [PATCH 21/35] Clean comments --- docs/css/custom_css.css | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/docs/css/custom_css.css b/docs/css/custom_css.css index 5f6e922..99ed466 100644 --- a/docs/css/custom_css.css +++ b/docs/css/custom_css.css @@ -1,13 +1,14 @@ +/* Make Tables Fullwidth */ .md-typeset__table { width: 100% !important; } - table { width: 100% !important; display: table !important; border-spacing: 0px !important; } +/* MkAutoDocs Styles */ div.autodoc-docstring { padding-left: 20px; margin-bottom: 30px; @@ -20,21 +21,14 @@ div.autodoc-members { } div.autodoc-signature *{ - /*display: none;*/ all: initial !important; - /* - font-style: italic !important; - font-feature-settings: "kern","liga" !important; - font-family: var(--md-text-font-family,_),-apple-system,BlinkMacSystemFont,Helvetica,Arial,sans-serif !important; - */ font-feature-settings: inherit !important; font-family: inherit !important; font-size: large !important; font-weight: 600 !important; - /*color: #36464e !important;*/ color: #7e54b9 !important; - /*background-color: #f5f5f5 !important;*/ } + em.autodoc-param{ font-style: italic !important; font-weight: 500 !important; From 8336ab64f7ac0c3a33a121ff1984ec530c8d41fc Mon Sep 17 00:00:00 2001 From: Justin Campbell Date: Fri, 2 Apr 2021 17:16:01 -0400 Subject: [PATCH 22/35] Finish installation docs --- docs/api/Installation.md | 84 ++++++++++++++-------------------------- 1 file changed, 29 insertions(+), 55 deletions(-) diff --git a/docs/api/Installation.md b/docs/api/Installation.md index 6552a27..f04d7ed 100644 --- a/docs/api/Installation.md +++ b/docs/api/Installation.md @@ -1,57 +1,31 @@ # Installation -The api is hosted as its own package in a dedicated git repository, https://github.itap.purdue.edu/ECN/webqueue2-api, and is easily installable via `pip`. - -### Install via command line -This is the syntax for installing the api: -``` -pip install git+https://github.itap.purdue.edu/ECN/webqueue2-api@#egg=webqueue2-api -``` -For example, to install version `0.9.1`, replace `` in the above command like this: -``` -pip install git+https://github.itap.purdue.edu/ECN/webqueue2-api@0.9.1#egg=webqueue2-api -``` - -### Install via requirements.txt -Append this line in the requirements file: -``` -git+https://github.itap.purdue.edu/ECN/webqueue2-api@#egg=webqueue2-api -``` -For example, to install version `0.9.1`, replace `` in the above line above like this: -``` -git+https://github.itap.purdue.edu/ECN/webqueue2-api@0.9.1#egg=webqueue2-api -``` -### Package Structure -The name of the package itself is `webqueue2-api` and follows this structure: -``` -─webqueue2-api (git repo) -│ -├───__init__.py -├───api.py -├───ECNQueue.py -└───setup.py -``` -**ECNQueue.py:** -The parser that iterates through items and resturns a json formatted string. - -**api.py:** -The bridge between the fronted and the parser: the frontend sends requests to `api.py` which are translated into functions present in the `ECNQueue.py`, and the json returned by `ECNQueue.py` is thus returned to the frontend. - -**setup.py:** -Stores important information about the `webqueue2-api` package including: - -* The version -* Dependencies that are installed with `webqueue2-api` -* The name of the package (`webqueue2-api`) -* The python version requirement, which is anything including and beyond python version 3.6 - -**\_\_init\_\_.py** -Specifies to `pip` that the current directory is a package, doesn't contain any code, but any code contained within `__init__.py` is executed when ever the `webqueue2-api` package is imported. - -### Importing the package - -The package cannot be referenced directly (need to check on this), however, both the `api` and `ECNQueue` modules can be directly imported after successfully installing the webqueue2-api package: -```python -import ECNQueue -import api -``` \ No newline at end of file +The webqueue2 API is publicly available at [{{ production_url }}/api]({{ production_url }}/api) but you can install it on your own machine if you'd like. + +The code is available on [GitHub]({{ config.repo_url }}). Available package versions can be seen on the [releases page]({{ config.repo_url }}/releases) and can be installed via pip, a requirements file, or downloaded and installed manually. + +!!! warning "pip available on ECN machines needs updated." + Installation via pip is possible through pip's [VCS support](https://pip.pypa.io/en/stable/reference/pip_install/#vcs-support) which was introduced in pip 19. The version of pip available on ECN supported machines is too old and needs updated. To update pip, run: + + ```bash + pip install -U pop + ``` + +=== "Install via pip" + To install webqueue2-api 0.9.1, you can run: + + ``` + pip install git+{{ config.repo_url }}@0.9.1#egg=webqueue2-api + ``` + + If you'd like a version other than 0.9.1 simply replace the that version number with a different version listed on the [releases page]({{ config.repo_url }}/releases). + +=== "Install via requirements file" + To install webqueue2-api 0.9.1, place the following line your requirements file: + + ```bash + echo "git+{{ config.repo_url }}@0.9.1#egg=webqueue2-api" >> requirements.txt + pip install -r requirements.txt + ``` + + If you'd like a version other than 0.9.1 simply replace the that version number with a different version listed on the [releases page]({{ config.repo_url }}/releases). \ No newline at end of file From 3f3f2418c1ea8c5041212d3a730181a94624a85f Mon Sep 17 00:00:00 2001 From: Justin Campbell Date: Fri, 2 Apr 2021 17:16:30 -0400 Subject: [PATCH 23/35] Remove code formatting for URL --- docs/api/Getting Started.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/Getting Started.md b/docs/api/Getting Started.md index e43f0fe..128d990 100644 --- a/docs/api/Getting Started.md +++ b/docs/api/Getting Started.md @@ -2,7 +2,7 @@ The webqueue2 API is organized around [REST](https://en.wikipedia.org/wiki/Representational_state_transfer). The API has resource oriented URLs, accepts and returns JSON encoded request bodies, can be modified via the query string and uses standard HTTP response codes and verbs. -You can use the webqueue2 API hosted at `{{ production_url }}/api` or [install it on your own machine](Installation.md). +You can use the webqueue2 API hosted at [{{ production_url }}/api]({{ production_url }}/api) or [install it on your own machine](Installation.md). ## Basic Usage From 47595e1fb6388b8c8ddfbe08ecd51a5cb622b421 Mon Sep 17 00:00:00 2001 From: Justin Campbell Date: Fri, 2 Apr 2021 17:16:44 -0400 Subject: [PATCH 24/35] Update repo URL --- mkdocs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkdocs.yml b/mkdocs.yml index 090fdf5..a84adcf 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -4,7 +4,7 @@ ################################################################################ site_name: webqueue2 API -repo_url: https://github.itap.purdue.edu/ECN/webqueue2 +repo_url: https://github.itap.purdue.edu/ECN/webqueue2-api plugins: - search # Awesome Pages Settings From a6740a4dbe09667617d3b29e2fb12bc316769f5d Mon Sep 17 00:00:00 2001 From: Justin Campbell Date: Sat, 3 Apr 2021 01:50:50 -0400 Subject: [PATCH 25/35] Finish Items docs --- docs/api/Items.md | 420 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 420 insertions(+) diff --git a/docs/api/Items.md b/docs/api/Items.md index 1eea0ec..381581f 100644 --- a/docs/api/Items.md +++ b/docs/api/Items.md @@ -1 +1,421 @@ # Items + +An item is a chronological representation of an interaction with a user. + +## Properties + +### `Item.lastUpdated` +Type | Description +- | - +`String` | An ISO 8601 formatted time string showing the last time the file was updated according to the filesystem. + +!!! example + ```js + console.log(Item.lastUpdated) + // Expected Output + "2021-04-03T00:48:38+00:00" + ``` + + +### `Item.headers` +Type | Description +- | - +`Array` | An array of objects containing parsed item headers in `type`/`value` pairs. + +!!! example + ```js + console.log(Item.headers[0]) + // Expexted Output + { type: "From", content: "\"Campbell, Justin Tyler\" \n"} + ``` + +### `Item.content` +Type | Description +- | - +`Array` | A chronological array of objects representing 1 of 9 possible actions taken on an item. + +**Possible Actions** +??? example "Directory Information" + Information about the user info collected from ECNDB including but not limited to alias, phone number and office location. + + ??? info "Properties" + | Key | Value | + | - | - | + |`type`|`directory_information`| + | `Name` | The real name of the sender. | + | `Login` | The career account alias of the sender. | + | `Computer` | The computer the item is related to. Formatting may vary. | + | `Location` | Where the computer is located. | + | `Email` | The email address of the sender. | + | `Phone` | The phone number of the sender. | + | `Office` | The office location of the sender. | + | `UNIX Dir` | The home directory for the user on non-Windows systems | + | `Zero Dir` | The home directory for the user via Active Directory | + | `User ECNDB` | Link to the sender's username report in ECNDB | + | `Host ECNDB` | Link to the computer report in ECNDB | + | `Subject` | The subject of the email sent to the queue | + + ??? quote "Parsed Example" + ```js + { + "type": "directory_information", + "Name": "Nestor Fabian Rodriguez Buitrago", + "Login": "rodri563", + "Computer": "ce-205-38 (128.46.205.67)", + "Location": "HAMP G230", + "Email": "rodri563@purdue.edu", + "Phone": "7654766893", + "Office": "HAMP G230", + "UNIX Dir": "/home/bridge/b/rodri563", + "Zero Dir": "U=\\\\bridge.ecn.purdue.edu\\rodri563", + "User ECNDB": "http://eng.purdue.edu/jump/2e8399a", + "Host ECNDB": "http://eng.purdue.edu/jump/2e83999", + "Subject": "Autocad installation" + } + ``` +??? example "Initial Message" + The body of the email the item originated from. + + ??? info "Properties" + | Key | Value | + | - | - | + | `type` | `initial_message` | + | `datetime` | RFC 8061 formatted datetime string. | + | `from_name` | The sender's real name. Formatting may vary. This can be empty. | + | `from_email` | The sender's email address. | + | `to` | A list of names(s) and email(s) of people this message was sent to. | + | `cc` | A list of name(s) and email(s) of people who were CC'd. This can be empty. | + | `subject` | The subject of the initial message. | + | `content` | The content of the message as an list of strings. | + + ??? quote "Parsed Example" + ```js + { + "type": "initial_message", + "datetime": "2020-09-11T01:26:45+00:00", + "from_name": "Justin Campbell", + "from_email": "campb303@purdue.edu", + "to": [ + { "name": "John Doe", "email": "johndoe@example.com" }, + ], + "cc": [ + { "name": "", "email": "janesmith@example.com" } + ], + "subject": Maps to item.subject, + "content": [ + "I need some help with something.\n" + ] + } + ``` +??? example "Edit" + Information added by someone at ECN, usually for internal use and/or communication. + + ??? info "Properties" + | Key | Value | + | - | - | + | `type` | `edit` | + | `datetime` | RFC 8061 formatted datetime string. | + | `by` | The career account alias of the person who added the edit. | + | `content` | The content of the edit as a list of strings. | + + ??? quote "Parsed Example" + ```js + { + "type": "edit", + "datetime": "2020-04-22T16:39:51", + "by": "knewell", + "content": [ + "This is related to another item. I need to do X next.\n" + ] + } + ``` +??? example "Status" + A short message about the progress of the item. + + ??? info "Properties" + | Key | Value | + | - | - | + | `type` | `status` | + | `datetime` | RFC 8061 formatted datetime string. | + | `by` | The career account alias of the person who updated the status. | + | `content` | The content of the status as a list of strings. | + + ??? quote "Parsed Example" + ```js + { + "type": "status", + "datetime": "2020-04-23T10:35:47", + "by": "knewell", + "content": [ + "Doing X thing." + ] + } + ``` +??? example "Assignment" + Assigning the item to someone. + + ??? info "Properties" + | Key | Value | + | - | - | + | `type` | `assignment` | + | `datetime` | RFC 8061 formatted datetime string. | + | `by` | The career account alias of the person who changed the |assignment. | + | `to` | The career account alias of the person who the item was assigned to. | + + ??? quote "Parsed Example" + ```js + { + "type": "assignment", + "datetime": "2020-06-23T13:27:00", + "by": "harley", + "to": "campb303", + } + ``` +??? example "Reply To User" + A message from ECN to the user and/or related parties. + + ??? info "Properties" + | Key | Value | + | - | - | + | `type` | `reply_to_user` | + | `datetime` | RFC 8061 formatted datetime string. | + | `by` | The sender's real name. Formatting may vary. This can be empty. | + | `content` | The content of the message as an list of strings | + + ??? quote "Parsed Example" + ```js + { + "type": "reply_to_user", + "datetime": "2020-05-08T09:21:43", + "by": "ewhile", + "content": [ + "Sascha,\n", + "\n", + "Chicken kevin biltong, flank jowl prosciutto shoulder meatball meatloaf sirloin.\n", + "\n", + "Ethan White\n", + "ECN" + ] + } + ``` +??? example "Reply To User" + A message from ECN to the user and/or related parties. + + ??? info "Properties" + | Key | Value | + | - | - | + | `type` | `reply_to_user` | + | `datetime` | RFC 8061 formatted datetime string. | + | `by` | The sender's real name. Formatting may vary. This can be empty. | + | `content` | The content of the message as an list of strings | + + ??? quote "Parsed Example" + ```js + { + "type": "reply_to_user", + "datetime": "2020-05-08T09:21:43", + "by": "ewhile", + "content": [ + "Sascha,\n", + "\n", + "Chicken kevin biltong, flank jowl prosciutto shoulder meatball meatloaf sirloin.\n", + "\n", + "Ethan White\n", + "ECN" + ] + } + ``` +??? example "Reply From User" + A message from the user and/or related parties. + + ??? info "Properties" + | Key | Value | + | - | - | + | `type` | `reply_from_user` | + | `datetime` | RFC 8061 formatted datetime string. | + | `from_name` | The sender's real name. Formatting may vary. This can be empty. | + | `from_email` | The sender's email address. | + | `cc` | A list of name(s) and email(s) of people who were CC'd. This can be empty. | + | `headers` | A dictionary of headers from the reply. | + | `subject` | The subject of the reply. | + | `content` | The content of the message as an list of strings | + + ??? quote "Parsed Example" + ```js + { + "type": "reply_from_user", + "datetime": "2020-05-08T13:57:18+00:00", + "from_name": "Reckowsky, Michael J.", + "from_email": "mreckowsky@purdue.edu", + "cc": [ + { "name": "John Doe", "email": "johndoe@example.com" }, + { "name": "", "email": "janesmith@example.com" } + ], + "headers" : [ + { + "type": "Subject", + "content": "RE: New Computer Deploy" + }, + { + "type": "From", + "content": "\"Reckowsky, Michael J.\" " + }, + { + "type": "Date", + "content": "Fri, 8 May 2020 13:57:17 +0000" + }, + ], + "subject": "RE: New Computer Deploy", + "content": [ + "Ethan,\n", + "\n", + "Biltong beef ribs doner chuck, pork chop jowl salami cow filet mignon pork.\n", + "\n", + "Mike\n", + ] + } + ``` +??? example "Parse Error" + An error caused by a malformed delimiter or nested delimiters. + + ??? info "Properties" + | Key | Value | + | - | - | + |`type`|`parse_error`| + | `datetime` | RFC 8061 formatted datetime string. | + | `file_path` | Full path of the item with the error. | + | `expected` | Description of what the parser was expecting. | + | `got` | Line that cause the parse error. | + | `line_num` | The line number in the item that caused the parse error. | + + ??? quote "Parsed Example" + ```js + { + 'type': 'parse_error', + 'datetime': '2020-10-16T10:44:45', + 'file_path': '/home/pier/e/benne238/webqueue2/q-snapshot/aae/2', + 'expected': 'Did not encounter a reply-from-user ending delimiter', + 'got': 'Kris', + 'line_num': 468 + } + ``` + +### `Item.isLocked` +Type | Description +- | - +`Boolean` | A boolean showing whether or not a lockfile for the item is present. + +!!! example + ```js + console.log(Item.isLocked) + // Expexted Output + true + ``` + +### `Item.userEmail` +Type | Description +- | - +`String` | The email address of the person who this item is from. + +!!! example + ```js + console.log(Item.userEmail) + // Expexted Output + "campb303@purdue.edu" + ``` + +### `Item.userName` +Type | Description +- | - +`String` | The real name of the person who this item is from. + +!!! example + ```js + console.log(Item.userName) + // Expexted Output + "Justin Campbell" + ``` + +### `Item.userAlias`: +Type | Description +- | - +`String` | The Purdue career account alias of the person this item is from. + +!!! example + ```js + console.log(Item.userAlias) + // Expexted Output + "campb303" + ``` + +### `Item.assignedTo`: +Type | Description +- | - +`String` | The Purdue career account alias of the person this item is assigned to. + +!!! example + ```js + console.log(Item.assignedTo) + // Expexted Output + "sundeep" + ``` + +### `Item.subject:` +Type | Description +- | - +`String` | The subject of the original message for this item. + +!!! example + ```js + console.log(Item.subject) + // Expexted Output + "Can't Access Outlook" + ``` + +### `Item.status` +Type | Description +- | - +`String` | The most recent status update for the item. + +!!! example + ```js + console.log(Item.status) + // Expexted Output + "Waiting for Reply" + ``` + +### `Item.priority:` +Type | Description +- | - +`String` | The most recent priority for this item. + +!!! example + ```js + console.log(Item.priority) + // Expexted Output + "COVID" + ``` + +### `Item.department` +Type | Description +- | - +`String` | The most recent department for this item. + +!!! example + ```js + console.log(Item.department) + // Expexted Output + "Bussiness Office" + ``` + +### `Item.dateReceived` +Type | Description +- | - +`String` | An ISO 8601 formatted time string showing the date this item was created. + +!!! example + ```js + console.log(Item.dateReceived) + // Expexted Output + "2021-04-03T00:48:38+00:00" + ``` \ No newline at end of file From 468b23afc9ca605f8bcbea1c4ba98e0359a82d44 Mon Sep 17 00:00:00 2001 From: Justin Campbell Date: Sat, 3 Apr 2021 02:01:22 -0400 Subject: [PATCH 26/35] Finish Queues docs --- docs/api/Queues.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/docs/api/Queues.md b/docs/api/Queues.md index c7b35ed..4501f34 100644 --- a/docs/api/Queues.md +++ b/docs/api/Queues.md @@ -1 +1,33 @@ # Queues + +A collection of [Items](/api/Items/). + +## Properties + +### `Queue.name` +Type | Description +- | - +`String` | The name of the queue. + +!!! example + ```js + console.log(Queue.name) + // Expected Output + "ce" + ``` + +### `Queue.items` +Type | Description +- | - +`Array` | The [Items](/api/Items/) in the queue. + +!!! example + ```js + console.log(Queue.items) + // Expected Output + [ + { queue: "ce", number: 01, lastUpdated: "2021-03-26T17:12:00-0400" ... } + { queue: "ce", number: 02, lastUpdated: "2021-05-29T17:12:00-0400" ... } + { queue: "ce", number: 03, lastUpdated: "2020-12-29T17:12:00-0400" ... } + ] + ``` \ No newline at end of file From 59aea43e32ade16bf68d2d8787e3d035e3a4724f Mon Sep 17 00:00:00 2001 From: Justin Campbell Date: Sat, 3 Apr 2021 23:53:46 -0400 Subject: [PATCH 27/35] Remove MkAutoDocs file --- docs/ecnqueue.md | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 docs/ecnqueue.md diff --git a/docs/ecnqueue.md b/docs/ecnqueue.md deleted file mode 100644 index 7d44c8a..0000000 --- a/docs/ecnqueue.md +++ /dev/null @@ -1,16 +0,0 @@ -# ECNQueue documentation - -::: webqueue2_api.ECNQueue - :docstring: - -## Item Class - -::: webqueue2_api.ECNQueue.Item - :docstring: - :members: - -## Queue Class - -::: webqueue2_api.ECNQueue.Queue - :docstring: - :members: From 897a9767e9078e0af05751796eaceee8d53db8ae Mon Sep 17 00:00:00 2001 From: Justin Campbell Date: Sat, 3 Apr 2021 23:53:59 -0400 Subject: [PATCH 28/35] Remove rest operator in nav --- docs/awesome-pages.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/awesome-pages.yaml b/docs/awesome-pages.yaml index 1cacee8..0e8234b 100644 --- a/docs/awesome-pages.yaml +++ b/docs/awesome-pages.yaml @@ -2,5 +2,4 @@ # See: https://github.com/lukasgeiter/mkdocs-awesome-pages-plugin nav: - index.md - - API: api - - ... \ No newline at end of file + - API: api \ No newline at end of file From e1bea815c7d4053b49d309038130fb9703c81d28 Mon Sep 17 00:00:00 2001 From: Justin Campbell Date: Sat, 3 Apr 2021 23:54:09 -0400 Subject: [PATCH 29/35] Add endpoint docs to Item --- docs/api/Items.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/docs/api/Items.md b/docs/api/Items.md index 381581f..9d14e8f 100644 --- a/docs/api/Items.md +++ b/docs/api/Items.md @@ -2,6 +2,28 @@ An item is a chronological representation of an interaction with a user. +## Endpoint +``` +GET /api/{queue}/{number} +``` +### Parameters +Name | Value +- | - +`queue` | The queue of the item. +`number` | The number of the item. + +### Query String Options +Name | Description | Possible Values +- | - | - +`headersOnly` | When `"True"`, only meta data will be loaded. When `"False"` content will be parsed. (Defaults to `"False"`.) | `"True"` \| `"False"` + +### Return Codes +Code | Description +- | - +`200 - Ok` | On success. +`500 - Internal Service Error` | On failure. + + ## Properties ### `Item.lastUpdated` From 52d91ef35b038277432830536271b0a0e273095b Mon Sep 17 00:00:00 2001 From: Justin Campbell Date: Sat, 3 Apr 2021 23:55:47 -0400 Subject: [PATCH 30/35] Add enpoint docs to Queue --- docs/api/Queues.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/docs/api/Queues.md b/docs/api/Queues.md index 4501f34..0ef4ce9 100644 --- a/docs/api/Queues.md +++ b/docs/api/Queues.md @@ -2,6 +2,26 @@ A collection of [Items](/api/Items/). +## Endpoint +``` +GET /api/{queue} +``` +### Parameters +Name | Value +- | - +`queue` | The name of the queue. + +### Query String Options +Name | Description | Possible Values +- | - | - +`headersOnly` | When `"True"`, only meta data will be loaded. When `"False"` content will be parsed. (Defaults to `"False"`.) | `"True"` \| `"True"` + +### Return Codes +Code | Description +- | - +`200 - Ok` | On success. +`500 - Internal Service Error` | On failure. + ## Properties ### `Queue.name` From d972fd81c6bf41f980936991f430bbf6f48a4468 Mon Sep 17 00:00:00 2001 From: Justin Campbell Date: Sat, 3 Apr 2021 23:57:09 -0400 Subject: [PATCH 31/35] Remove overview doc --- docs/api/API Overview.md | 177 --------------------------------------- 1 file changed, 177 deletions(-) delete mode 100644 docs/api/API Overview.md diff --git a/docs/api/API Overview.md b/docs/api/API Overview.md deleted file mode 100644 index 6384e0d..0000000 --- a/docs/api/API Overview.md +++ /dev/null @@ -1,177 +0,0 @@ -# *(draft)* API Overview -Using Flask, Flask Restful and Flask JWT (correct?) The api works as a direct connection to the storage for the items stored by the Qcli, allowing front end calls to request parsed information via url. - -Endpoints | Use -:---: | :--- -[**/api/login**](#login) | Receives a JSON encoded username and password. Sets a Refresh token cookie and returns an access token. -[**/api/tokens/refresh**](#tokensrefresh) | Gets a new refresh token. -[**/api/data/<string:queue>/<int:number>**](#acessing-items) | Returns a JSON encoded Item. -[**/api/data/<string:queues>**](#accessing-queues) | Returns a JSON encoded Queue. -[**/api/data/get_queues**](#accessing-queue-counts) | Returns a list of queues and their item counts. - -## login - -#### **Description** -Acts as a way to authenticate users to access data parsed in the back end. - -#### **Arguments** -The api login accpets a username and an already hashed password. -```json -{ - "username": form.username, - "password": sha256(form.password) -} -``` -The api accepts the hashed password and salts and hashes it an additional time and attempts to authenticate the username and the password using *insert part of flask being used here*. - -#### **Returns** -After sucesfully authenticating the username and password, the api will return an access token to then be stored in a browser cookie on the frontend -```json -{ "access_token": access_token } -``` - -#### **Errors** - -| Error | Reason | -| ---- | ---- | -| **422** | Returns if data is not json or if the json data is not formatted correctly | -| **401** | Returns if the username and/or password is invalid | - -## tokens/refresh - -#### **Description** - -Acts as a revalidation of an already authenticated user and supplies a newly created access token. - -## Acessing Items - -#### **Description** - -Items are individual "tickets", stored in a collective queue with other items. Item numbers are unique only within each queue, meaning that to access a specific item, its queue name must also be known in addition to it's item number. `ce100`, `me23`, and `eee48` would all be specific items that can all be accessed. - -#### **Arguments** - -**/api/data/*<string:queue>*/*<int:number>*** - -Argument | Type | Description -:---- | :----: | :---- -`queue` | String | The queue an item is located in -`item` | Int | The item's distinct number within the specified queue -`headersOnly` *(Optional)* | Boolean | Specify weather to only returns the headers of an item or the whole item - -An item can be accessed directly from the url by passing the queue name and the item number. -By default, the entire contents of an item are returned, but the headers of an item, without any of the content within that item, can also be returned by passing the `headersOnly=True` argument within the url: - -`/api/data/ce/100` will default to `headersOnly=False` and return the entirety of `ce 100` - -`/api/data/ce/100?headersOnly=True` will return only the headers of `ce 100` - -#### **Returns** - -When `headersOnly=False`, the full contents of an item will be returned in a json structure with these keys: - -Key | Value -------|------ -`lastUpdated` | An ISO 8601 formatted time string showing the last time the file was updated. -`headers` | A list of dictionaries containing header keys and values. -`content` | A list of section dictionaries. -`isLocked` | A boolean showing whether or not a lockfile for the item is present. -`userEmail` | The email address of the person who this item is from. -`userName` | The real name of the person who this item is from. -`userAlias` | The Purdue career account alias of the person this item is from. -`assignedTo` | The Purdue career account alias of the person this item is assigned to -`subject` | The subject of the original message for this item. -`status` | The most recent status update for the item. -`priority` | The most recent priority for this item. -`department` | The most recent department for this item. -`dateReceived` | The date this item was created. -`jsonData` | A JSON serializable representation of the Item. - -If `headersOnly=True`, then all of the key/value pairs are returned except for the `content` key and the list of dictionaries associated with it. - -## Accessing Queues - -#### **Description** - -Additionally, the information relating to all items in a queue can be accesed by simply naming the queue in the URL. Unlike acessing a specific item, acessing a queue only returns the header information for each item to decrease the time it takes to parse the information from the stored items. - -#### **Arguments** - -Accessing a queue is similar to accessing an individual item except that multiple item dictionaries are returned within a list as opposed to just one item in a singular dictionary. - -**/api/data/*<string:queues>*** - -| Argument | Type | Description | -| ---- | :----: | :---- | -| `queue` | String | The name of a queue | -| `headersOnly` *(Optional)* | Boolean | Specify weather to only returns the headers of an item or the whole item | - -By default, acessing an entire queue will return only the header information for the items within a given queue, however, it is possible to return the entire contents of all the items within a queue by passing `headersOnly=False` within the url: - -| URL | Return Description | -| --- | --- | -| `/api/data/me` | Defaults to `headersOnly=True` and returns a list of all items in the `me` queue with only the header information included. | -| `/api/data/ce?headersOnly=False` | Returns a list of all the items in the `me` queue with the entire contents of every item included. | - -It is also possible to return multiple queues by passing more than one queue name in the url. separating each queue name with "+": - -| URL | Return Description | -| --- | --- | -| `/api/data/eee+cnit` | Defaults to `headersOnly=True` and returns a list of all the items in both the `eee` and `cnit` queues with only the header information included. | -| `/api/data/eee+cnit?headersOnly=False` | Returns a list of all the items in both the `eee` and `cnit` queues with the entire contents of every item from both queues included. | - -#### **Returns** - -Returns a list of queues, with each queue being it's own dictionary with a list of items, each item represented by a dictionary. - -**JSON output:** -```json -[ - {'name': 'queue_name', - 'items': ['list_of_item_dictionaries] - }, - - {'name': 'queue_name', - 'items': ['list_of_item_dictionaries] - } -] -``` -## Accessing Queue Counts - -#### **Description** - -This will return a dictionary of all valid queues with the number of items within each queue. - -#### **Arguments** - -This function doesn't require any arguments from the url. - -#### **Returns** - -Returns a list of dictionaries with these key value pairs: -**/api/data/get_queues** - -| Key | Type | Value | -| --- | ---- | ----- | -| `name` | string | the name of the queue | -| `number_of_items` | int | the number of items within the queue | - -**JSON output:** -```json -[ - { - 'name': 'bidc', - 'number_of_items': 5 - }, - - { - 'name': 'epics', - 'number_of_items': 6 - }, - - { - 'name': 'wang', - 'number_of_items': 13 - } -] -``` \ No newline at end of file From d635c864c52fd3e3adb157cc330dbaa10f92870b Mon Sep 17 00:00:00 2001 From: Justin Campbell Date: Sun, 4 Apr 2021 00:05:30 -0400 Subject: [PATCH 32/35] Remove MkAutoDocs plugin --- setup.py | 1 - 1 file changed, 1 deletion(-) diff --git a/setup.py b/setup.py index c6cfdac..b22ce74 100644 --- a/setup.py +++ b/setup.py @@ -8,7 +8,6 @@ "docs": [ "mkdocs", "mkdocs-material", - "mkautodoc", "mkdocs-awesome-pages-plugin", "mkdocs-macros-plugin" ], From 4e67580551a060dc70e4cb34332821a667cf9e2d Mon Sep 17 00:00:00 2001 From: Justin Campbell Date: Sun, 4 Apr 2021 00:08:45 -0400 Subject: [PATCH 33/35] Remove MkAutoDocs from MkDocs --- mkdocs.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/mkdocs.yml b/mkdocs.yml index a84adcf..2cda46b 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -26,7 +26,6 @@ markdown_extensions: - pymdownx.emoji: emoji_index: !!python/name:materialx.emoji.twemoji emoji_generator: !!python/name:materialx.emoji.to_svg - - mkautodoc From 5d885fac35d8713b7dd1659cb67407f10f252ba3 Mon Sep 17 00:00:00 2001 From: Justin Campbell Date: Sun, 4 Apr 2021 00:18:49 -0400 Subject: [PATCH 34/35] Remove MkAutoDocs styles --- docs/css/custom_css.css | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/docs/css/custom_css.css b/docs/css/custom_css.css index 99ed466..f1ca50a 100644 --- a/docs/css/custom_css.css +++ b/docs/css/custom_css.css @@ -6,34 +6,4 @@ table { width: 100% !important; display: table !important; border-spacing: 0px !important; -} - -/* MkAutoDocs Styles */ -div.autodoc-docstring { - padding-left: 20px; - margin-bottom: 30px; - border-left: 5px solid rgba(230, 230, 230); -} - -div.autodoc-members { - padding-left: 20px; - margin-bottom: 15px; -} - -div.autodoc-signature *{ - all: initial !important; - font-feature-settings: inherit !important; - font-family: inherit !important; - font-size: large !important; - font-weight: 600 !important; - color: #7e54b9 !important; -} - -em.autodoc-param{ - font-style: italic !important; - font-weight: 500 !important; -} - -.autodoc-docstring{ - border-color: #977fb8 !important; } \ No newline at end of file From 651da8200bd88f07ea7124fb52b2ce8787a029e5 Mon Sep 17 00:00:00 2001 From: Justin Campbell Date: Sun, 4 Apr 2021 00:27:14 -0400 Subject: [PATCH 35/35] Add basic home page --- docs/index.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/index.md b/docs/index.md index e69de29..80934d4 100644 --- a/docs/index.md +++ b/docs/index.md @@ -0,0 +1 @@ +See the [API Docs](api/Getting Started/). \ No newline at end of file