I have written the following Python code to generate a SAS token for a file placed in an Azure file share directory:
def getParcelFilePath(webcountyval):
filePath = rf"/plan/IN/{webcountyval}%20parcels.dbf"
file_sas_token = generate_file_sas(
account_name=os.environ["AZURE_STORAGE_ACCOUNT_NAME"],
account_key=os.environ["AZURE_STORAGE_ACCOUNT_KEY"],
share_name="dev",
file_path=filePath,
permission=AccountSasPermissions(read=True),
expiry=datetime.datetime.now() + datetime.timedelta(hours=8),
start=datetime.datetime.now()
)
filePathWithToken = os.environ["AZURE_STORAGE_SHARE_URL"] + filePath + "?" + file_sas_token
return(filePathWithToken)
I live in the Central time zone. To ensure that the authentication does not fail, you can see that I have passed 8 hours to the timedelta() function.
The following URL is generated for the file: https://crestlinecapitalstorage.file.core.windows.net/dev/plan/IN/elkhart%20parcels.dbf?st=2024-11-11T23%3A14%3A30Z&se=2024-11-12T07%3A14%3A30Z&sp=r&sv=2024-11-04&sr=f&sig=[redacted_sig]
When I paste this URL into the browser, it shows the following error: Signature did not match. String to sign used was r 2024-11-11T23:14:30Z 2024-11-12T07:14:30Z /file/crestlinecapitalstorage/dev/plan/IN/elkhart parcels.dbf 2024-11-04
What could be the reason for the error?
It is quite possible that the file_path value “/plan/in/{webcountyval}%20parcels.dbf” was incorrect. The extra ‘/’ at the beginning may not be needed. Anyway, instead of spending any more nightmarish moments trying to get the URL with a SAS token to work, I found a workaround, which is easier to work with and maintain (see AI Overview provided by Google search).
Here's the final code:
def getFileClient(stateval, webcountyval):
filePath = rf"plan/{stateval}/{webcountyval} parcels.dbf"
accountKey = os.environ["AZURE_STORAGE_ACCOUNT_KEY"]
shareName = "dev"
# Create a ShareClient object
shareClient = ShareClient(
account_url=os.environ["AZURE_STORAGE_ACCOUNT_URL"],
credential=accountKey,
share_name=shareName
)
# Get a reference to the file
fileClient = shareClient.get_file_client(filePath)
return(fileClient)
def parcelDBFDataSave(parcelFileClient):
# Download the file
fileContent = parcelFileClient.download_file().readall()
with tempfile.NamedTemporaryFile(delete=False) as tempParcelFile:
tempParcelFile.write(fileContent)
tempParcelFileName = tempParcelFile.name
# Read the first five records
with DBF(tempParcelFileName) as dbfRecords:
i = 0
for record in dbfRecords:
logging.info(record)
i += 1
if i > 5: break
return(SUCCESS)
ccParcelFileClient = getFileClient(stateabbr, webCounty)
result = parcelDBFDataSave(ccParcelFileClient)