Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upload media via REST API #770

Closed
NicoHood opened this issue Apr 6, 2022 · 7 comments
Closed

Upload media via REST API #770

NicoHood opened this issue Apr 6, 2022 · 7 comments
Assignees
Labels
enhancement New feature or request

Comments

@NicoHood
Copy link
Contributor

NicoHood commented Apr 6, 2022

I try to upload media files using the REST API:
https://listmonk.app/docs/apis/media/

The API and the example says I must use multipart/form-data but I am new to this. Can you maybe go more into detail how to upload a file? Especially I want to upload the file via python.

For reference, this is how I do it with the wordpress rest api:

headers = {
    "Content-Type": mimetypes.guess_type(filename)[0],
    "Accept": "application/json",
    "Content-Disposition": f"attachment; filename={filename}",
}

Also: How do I search for existing media files? It does not seem this is documented. The get curl example also contains some multipart/form-data, I am not sure if that is correct.

@NicoHood
Copy link
Contributor Author

NicoHood commented Apr 6, 2022

I found some more python samples, but still not working:

        url = f"{self.base_url}/api/media"

        headers = {
            # "Content-Type": 'multipart/form-data;boundary="boundary"',
            "Accept": "application/json"
            # "Content-Disposition": f"attachment; filename={filename}",
        }

        logging.info(f"Uploading media to {url}")
        # https://2.python-requests.org/en/master/user/quickstart/#post-a-multipart-encoded-file
        # https://2.python-requests.org/en/master/user/advanced/#multipart
        files = { "foo": ("filename.csv", 'testcontent', mimetypes.guess_type(filename)[0]) }
        response = requests.post(url, headers=headers, auth=self.__auth, files=files)
        if response.status_code != 201:
            logging.critical(f"Error uploading media file: {response.status_code} {response.text}")
            sys.exit(1)
# --> CRITICAL:root:Error uploading media file: 400 {"message":"Ungültige Datei: http: no such file"}

@NicoHood
Copy link
Contributor Author

NicoHood commented Apr 6, 2022

I was able to get it working:

    def upload_media_file(self, image: BinaryIO, filename: str) -> None:
        url = f"{self.base_url}/api/media"

        logging.info(f"Uploading media to {url}")
        # https://2.python-requests.org/en/master/user/quickstart/#post-a-multipart-encoded-file
        # https://2.python-requests.org/en/master/user/advanced/#multipart
        files = { "file": (filename, image, mimetypes.guess_type(filename)[0]) }
        response = requests.post(url,  auth=self.__auth, files=files)
        if response.status_code != 200:
            logging.critical(f"Error uploading media file: {response.status_code} {response.text}")
            sys.exit(1)

        data = response.json()
        # print(json.dumps(data, indent=4, sort_keys=True))

        if data["data"] != True:
            logging.critical(f"Error uploading media file (invalid API response): {data}")
            sys.exit(1)

There is no documentation, that the name in this multipart form field should be file and not foo as in my case. I found that looking at the code and try/error.

Now I am wondering why I don't get any information about the uploaded media back. What if it already exists and was renamed? I need the newly generated url or at least an ID to further proceed. Is that possible somehow?

@knadh
Copy link
Owner

knadh commented Apr 7, 2022

Now I am wondering why I don't get any information about the uploaded media back. What if it already exists and was renamed?

Files with conflicting filenames get a new name, so there are no duplicate file errors or overrides.

I need the newly generated url or at least an ID to further proceed. Is that possible somehow?

You are right. This was missed. Will add the uploaded file's URL in the response.

@knadh knadh added the enhancement New feature or request label Apr 7, 2022
@knadh knadh self-assigned this Apr 7, 2022
@NicoHood
Copy link
Contributor Author

NicoHood commented Apr 7, 2022

Alright. I would expect the API to return a media object, similar to /api/media. This would be a breaking change, but makes a lot sense to me.

Also a dedicated get for /api/media/id would be nice.

And I need to search for existing media filename to avoid a reupload. Even better would be to even place a sha256 or sha512sum inside the response to check if the file matches without downloading it. The checksum could be added after uploading, as the file is processed anyways.

@NicoHood
Copy link
Contributor Author

NicoHood commented Apr 7, 2022

Another addition: The docs say, that the rest api returns a width and a height. But they don't do that for me.

Also thumb_uri and uri were renamed to url https://listmonk.app/docs/apis/media/

The provider is missing in the docs at all.

@knadh knadh closed this as completed in 77bc8a7 Jul 13, 2022
@NicoHood
Copy link
Contributor Author

Is it possible to get a media object by id now? Also how about searching for files via filename?

@knadh
Copy link
Owner

knadh commented Jul 18, 2022

Yes, it's possible. Turns out, it was always possible! /api/media/:id always worked.

Also how about searching for files via filename?

This is a new feature that we can consider adding. Will need a search box in the media UI as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants