Python script to download and upload packages through Octopus APIs

The code below is to download the package and upload the package without saving it to a file. Download the package into memory seems working, but uploading is not working. Can someone help me with it? Also, I may also want to download the package onto a local file and upload it through Python code later.

The swagger API is not clear to me https://demo.octopus.com/swaggerui/index.html#/Packages/CustomActionResponseDescriptor_Octopus_Server_Web_Api_Actions_PackageRepository_PackageRepositoryUploadAction__Spaces

================== Python code ================

download_response = requests.get(ā€œhttps://demo.octopus.com/api/Spaces-1/packages/packages-OctoFX.Database.3.5.3047/rawā€, headers=headers)
print(download_response.status_code)
print(len(download_response.content))

upload_response = requests.post(ā€œhttp://localhost/api/Spaces-1/packages/rawā€, files={ā€œupload_fileā€: download_response.content}, headers=headers)

=================== output =======================
200
1927575

Error code: 400; Reason: Bad Request; {ā€˜ErrorMessageā€™: ā€˜There was a problem with your request.ā€™, ā€˜Errorsā€™: [ā€˜A package file must be providedā€™], ā€˜ParsedHelpLinksā€™: []}
Traceback (most recent call last):
File ā€œD:/Docs/code/github/octopus-python-client/src/octopus_python_client/utilities/send_requests_to_octopus.pyā€, line 65, in call_octopus
err=f"Error code: {session_response.status_code}; Reason: "
File ā€œD:\Docs\code\github\octopus-python-client\src\octopus_python_client\utilities\helper.pyā€, line 194, in log_raise_value_error
raise ValueError(err)
ValueError: Error code: 400; Reason: Bad Request; {ā€˜ErrorMessageā€™: ā€˜There was a problem with your request.ā€™, ā€˜Errorsā€™: [ā€˜A package file must be providedā€™], ā€˜ParsedHelpLinksā€™: []}

Process finished with exit code 1

Greetings tonybest! I found an example in C# that may be able to help. Take a gander at https://github.com/OctopusDeploy/OctopusDeploy-Api/blob/master/Octopus.Client/LINQPad/Push%20Package%20to%20Built-In%20Repository.linq and see if that provides some clarification. If not, let me know :slight_smile:

I looked at this C# code yesterday. I like to see a Python example, if possible. Otherwise, I can dive deeper into the C# code. Thanks, Shawn

Hey there Tony! Thank you for bearing with me, I needed to wait until one of the engineers was available and theyā€™re all Australia based. One of the engineers was able to provide the following

import os
import requests

octopus_url = os.environ.get('octopus_url')
octopus_apikey = os.environ.get('octopus_apikey')

package_upload_url = '{0}/api/Spaces-1/packages/raw'.format(octopus_url)

# Octopus API Key Header

headers = {
'X-Octopus-ApiKey': octopus_apikey
}

# Package to Upload

package = {
'file': open('OctoFX.TradingWebsite.3.5.3047.nupkg', 'rb')
}

ā€‹response = requests.post(package_upload_url, files=package, headers=headers)

print(response)
1 Like

Shawn,

The code your provided works! I also found out why my code did not work. My headers had {ā€œContent-Typeā€: ā€œapplication/jsonā€}. After removing it, my code also works without saving the file locally.

Thank you again! Octopus rocks!

Awesome, glad it worked out for you :slight_smile:

Hi Shawn,

I need more help. By using the script, ZIP files cannot be uploaded.

Error code: 500; Reason: Internal Server Error; {ā€˜ErrorMessageā€™: ā€˜Nuspec file does not exist in package.ā€™}

ā€œ.nupkgā€ files can be uploaded though.

Thanks.

In Python, is there a way to specify

type=application/zip
1 Like

Hi Shawn,

I figured out.

When uploading data from memory (not from a local file), you need to specify the file_name in the payload

upload_response = requests.post(ā€œhttp://localhost/api/Spaces-1/packages/rawā€, files={ā€œupload_fileā€: (file_name, download_response.content)}, headers=headers)

Thank you.

Nice! Glad you were able to overcome that :slight_smile:

This topic was automatically closed 31 days after the last reply. New replies are no longer allowed.