We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Text Enrichment function not quoting blob paths correctly
We have some files with percentage (%) symbols in them, which appear to cause an issue when getting to the Text Enrichment stage of the Function App due to the way the `get_blob_and_sas` function works. Example file name: `Unemployment rate back up to 3.7% in October _ Australian Bureau of Statistics.pdf`

I would suggest replacing the code that manually substitutes spaces (below) with a proper URL quoting function like `blob_path = urllib.parse.quote(blob_path)`

https://github.com/microsoft/PubSec-Info-Assistant/blob/7fa4561652211b023965d4522b2bfd7168af4060/functions/shared_code/utilities_helper.py#L52




--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `functions/shared_code/utilities_helper.py`
Content:
```
1 # Copyright (c) Microsoft Corporation.
2 # Licensed under the MIT license.
3 
4 import os
5 import logging
6 from datetime import datetime, timedelta
7 from azure.storage.blob import generate_blob_sas, BlobSasPermissions
8 
9 class UtilitiesHelper:
10     """ Helper class for utility functions"""
11     def __init__(self,
12                  azure_blob_storage_account,
13                  azure_blob_storage_endpoint,
14                  azure_blob_storage_key
15                  ):
16         self.azure_blob_storage_account = azure_blob_storage_account
17         self.azure_blob_storage_endpoint = azure_blob_storage_endpoint
18         self.azure_blob_storage_key = azure_blob_storage_key
19         
20     def get_filename_and_extension(self, path):
21             """ Function to return the file name & type"""
22             # Split the path into base and extension
23             base_name = os.path.basename(path)
24             segments = path.split("/")
25             directory = "/".join(segments[1:-1]) + "/"
26             if directory == "/":
27                 directory = ""
28             file_name, file_extension = os.path.splitext(base_name)
29             return file_name, file_extension, directory
30     
31     def  get_blob_and_sas(self, blob_path):
32         """ Function to retrieve the uri and sas token for a given blob in azure storage"""
33 
34         # Get path and file name minus the root container
35         separator = "/"
36         file_path_w_name_no_cont = separator.join(
37             blob_path.split(separator)[1:])
38         
39         container_name = separator.join(
40             blob_path.split(separator)[0:1])
41 
42         # Gen SAS token
43         sas_token = generate_blob_sas(
44             account_name=self.azure_blob_storage_account,
45             container_name=container_name,
46             blob_name=file_path_w_name_no_cont,
47             account_key=self.azure_blob_storage_key,
48             permission=BlobSasPermissions(read=True),
49             expiry=datetime.utcnow() + timedelta(hours=1)
50         )
51         source_blob_path = f'{self.azure_blob_storage_endpoint}{blob_path}?{sas_token}'
52         source_blob_path = source_blob_path.replace(" ", "%20")
53         logging.info("Path and SAS token for file in azure storage are now generated \n")
54         return source_blob_path
```
--- END FILES ---

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

Here is an example:

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

```

diff --git a/functions/shared_code/utilities_helper.py b/functions/shared_code/utilities_helper.py
--- a/functions/shared_code/utilities_helper.py
+++ b/functions/shared_code/utilities_helper.py
@@ -3,6 +3,7 @@
 
 import os
 import logging
+import urllib.parse
 from datetime import datetime, timedelta
 from azure.storage.blob import generate_blob_sas, BlobSasPermissions
 
@@ -48,7 +49,7 @@
             permission=BlobSasPermissions(read=True),
             expiry=datetime.utcnow() + timedelta(hours=1)
         )
+        blob_path = urllib.parse.quote(blob_path)
         source_blob_path = f'{self.azure_blob_storage_endpoint}{blob_path}?{sas_token}'
-        source_blob_path = source_blob_path.replace(" ", "%20")
         logging.info("Path and SAS token for file in azure storage are now generated \n")
         return source_blob_path
\ No newline at end of file

{"golden_diff": "diff --git a/functions/shared_code/utilities_helper.py b/functions/shared_code/utilities_helper.py\n--- a/functions/shared_code/utilities_helper.py\n+++ b/functions/shared_code/utilities_helper.py\n@@ -3,6 +3,7 @@\n \n import os\n import logging\n+import urllib.parse\n from datetime import datetime, timedelta\n from azure.storage.blob import generate_blob_sas, BlobSasPermissions\n \n@@ -48,7 +49,7 @@\n             permission=BlobSasPermissions(read=True),\n             expiry=datetime.utcnow() + timedelta(hours=1)\n         )\n+        blob_path = urllib.parse.quote(blob_path)\n         source_blob_path = f'{self.azure_blob_storage_endpoint}{blob_path}?{sas_token}'\n-        source_blob_path = source_blob_path.replace(\" \", \"%20\")\n         logging.info(\"Path and SAS token for file in azure storage are now generated \\n\")\n         return source_blob_path\n\\ No newline at end of file\n", "issue": "Text Enrichment function not quoting blob paths correctly\nWe have some files with percentage (%) symbols in them, which appear to cause an issue when getting to the Text Enrichment stage of the Function App due to the way the `get_blob_and_sas` function works. Example file name: `Unemployment rate back up to 3.7% in October _ Australian Bureau of Statistics.pdf`\r\n\r\nI would suggest replacing the code that manually substitutes spaces (below) with a proper URL quoting function like `blob_path = urllib.parse.quote(blob_path)`\r\n\r\nhttps://github.com/microsoft/PubSec-Info-Assistant/blob/7fa4561652211b023965d4522b2bfd7168af4060/functions/shared_code/utilities_helper.py#L52\r\n\r\n\r\n\n", "before_files": [{"content": "# Copyright (c) Microsoft Corporation.\n# Licensed under the MIT license.\n\nimport os\nimport logging\nfrom datetime import datetime, timedelta\nfrom azure.storage.blob import generate_blob_sas, BlobSasPermissions\n\nclass UtilitiesHelper:\n    \"\"\" Helper class for utility functions\"\"\"\n    def __init__(self,\n                 azure_blob_storage_account,\n                 azure_blob_storage_endpoint,\n                 azure_blob_storage_key\n                 ):\n        self.azure_blob_storage_account = azure_blob_storage_account\n        self.azure_blob_storage_endpoint = azure_blob_storage_endpoint\n        self.azure_blob_storage_key = azure_blob_storage_key\n        \n    def get_filename_and_extension(self, path):\n            \"\"\" Function to return the file name & type\"\"\"\n            # Split the path into base and extension\n            base_name = os.path.basename(path)\n            segments = path.split(\"/\")\n            directory = \"/\".join(segments[1:-1]) + \"/\"\n            if directory == \"/\":\n                directory = \"\"\n            file_name, file_extension = os.path.splitext(base_name)\n            return file_name, file_extension, directory\n    \n    def  get_blob_and_sas(self, blob_path):\n        \"\"\" Function to retrieve the uri and sas token for a given blob in azure storage\"\"\"\n\n        # Get path and file name minus the root container\n        separator = \"/\"\n        file_path_w_name_no_cont = separator.join(\n            blob_path.split(separator)[1:])\n        \n        container_name = separator.join(\n            blob_path.split(separator)[0:1])\n\n        # Gen SAS token\n        sas_token = generate_blob_sas(\n            account_name=self.azure_blob_storage_account,\n            container_name=container_name,\n            blob_name=file_path_w_name_no_cont,\n            account_key=self.azure_blob_storage_key,\n            permission=BlobSasPermissions(read=True),\n            expiry=datetime.utcnow() + timedelta(hours=1)\n        )\n        source_blob_path = f'{self.azure_blob_storage_endpoint}{blob_path}?{sas_token}'\n        source_blob_path = source_blob_path.replace(\" \", \"%20\")\n        logging.info(\"Path and SAS token for file in azure storage are now generated \\n\")\n        return source_blob_path", "path": "functions/shared_code/utilities_helper.py"}], "after_files": [{"content": "# Copyright (c) Microsoft Corporation.\n# Licensed under the MIT license.\n\nimport os\nimport logging\nimport urllib.parse\nfrom datetime import datetime, timedelta\nfrom azure.storage.blob import generate_blob_sas, BlobSasPermissions\n\nclass UtilitiesHelper:\n    \"\"\" Helper class for utility functions\"\"\"\n    def __init__(self,\n                 azure_blob_storage_account,\n                 azure_blob_storage_endpoint,\n                 azure_blob_storage_key\n                 ):\n        self.azure_blob_storage_account = azure_blob_storage_account\n        self.azure_blob_storage_endpoint = azure_blob_storage_endpoint\n        self.azure_blob_storage_key = azure_blob_storage_key\n        \n    def get_filename_and_extension(self, path):\n            \"\"\" Function to return the file name & type\"\"\"\n            # Split the path into base and extension\n            base_name = os.path.basename(path)\n            segments = path.split(\"/\")\n            directory = \"/\".join(segments[1:-1]) + \"/\"\n            if directory == \"/\":\n                directory = \"\"\n            file_name, file_extension = os.path.splitext(base_name)\n            return file_name, file_extension, directory\n    \n    def  get_blob_and_sas(self, blob_path):\n        \"\"\" Function to retrieve the uri and sas token for a given blob in azure storage\"\"\"\n\n        # Get path and file name minus the root container\n        separator = \"/\"\n        file_path_w_name_no_cont = separator.join(\n            blob_path.split(separator)[1:])\n        \n        container_name = separator.join(\n            blob_path.split(separator)[0:1])\n\n        # Gen SAS token\n        sas_token = generate_blob_sas(\n            account_name=self.azure_blob_storage_account,\n            container_name=container_name,\n            blob_name=file_path_w_name_no_cont,\n            account_key=self.azure_blob_storage_key,\n            permission=BlobSasPermissions(read=True),\n            expiry=datetime.utcnow() + timedelta(hours=1)\n        )\n        blob_path = urllib.parse.quote(blob_path)\n        source_blob_path = f'{self.azure_blob_storage_endpoint}{blob_path}?{sas_token}'\n        logging.info(\"Path and SAS token for file in azure storage are now generated \\n\")\n        return source_blob_path", "path": "functions/shared_code/utilities_helper.py"}]}