Hi,
anybody here ever had to do anything with Rackspace's Storage API to move objects around?
I think I've seen Rackspace mentioned here before so I'm hoping.
I've got to copy a file from one container to another (actually it's a lot of files but I'm just trying to prove the concept).
I've managed to get the authentication sorted out which was defined like this:
$ curl https://identity.api.rackspacecloud.com/v2.0/tokens%C2%A0 \ -X POST \ -d '{"auth":{"RAX-KSKEY:apiKeyCredentials":{"username":"yourUserName","apiKey":"$apiKey"}}}' \ -H "Content-type: application/json"
I was able to translate that like this:
m.lcUrl = "https://identity.api.rackspacecloud.com/v2.0/tokens"
TEXT TO lcAuthBody NOSHOW TEXTMERGE { "auth": { "RAX-KSKEY:apiKeyCredentials": { "username": "<<UserName>>", "apiKey": "<<APIKey>>" } } } ENDTEXT
LOCAL loXmlHttp AS Microsoft.XMLHTTP
loXmlHttp = Newobject( "Microsoft.XMLHTTP" ) loXmlHttp.Open( "POST" , m.lcUrl, .F. ) loXmlHttp.setRequestHeader("Content-Type","application/json") loXmlHttp.Send( m.lcAuthBody )
I can then pull the token out of the loXmlHttp.responsetext
Now I want to use this token to copy a file from one container to another.
The documentation here (https://docs.rackspace.com/docs/cloud-files/v1/storage-api-reference/object-... ) gives this example:
COPY /v1/account/sourceContainer/sourceObject HTTP/1.1 Host: storageURL X-Auth-Token: yourAuthToken Destination: /destinationContainer/destinationObject
I don't know how to interpret this to make an xmlhttp call.
1. What is the url for the end point? I've got the account, sourceContainer and sourceObject but not sure what comes before the /v1/
2. I'm unaware of a COPY type of Http request, so what should that be?
3. Even trying various things in PostMan aren't helping :(
On May 12, 2022, at 13:10, Frank Cazabon frank.cazabon@gmail.com wrote:
anybody here ever had to do anything with Rackspace's Storage API to move objects around?
I think I've seen Rackspace mentioned here before so I'm hoping.
I've got to copy a file from one container to another (actually it's a lot of files but I'm just trying to prove the concept).
I wrote the Python SDK for Rackspace (actually, all of OpenStack), and here's the code for copying one object to another container:
@_handle_container_not_found def copy_object(self, container, obj, new_container, new_obj_name=None, content_type=None): """ Copies the object to the new container, optionally giving it a new name. If you copy to the same container, you must supply a different name.
Returns the etag of the newly-copied object.
You can optionally change the content_type of the object by supplying that in the 'content_type' parameter. """ nm = new_obj_name or utils.get_name(obj) uri = "/%s/%s" % (utils.get_name(new_container), nm) copy_from = "/%s/%s" % (utils.get_name(container), utils.get_name(obj)) headers = {"X-Copy-From": copy_from, "Content-Length": "0"} if content_type: headers["Content-Type"] = content_type resp, resp_body = self.api.method_put(uri, headers=headers) return resp.headers.get("etag")
To translate to English, the URI is the base URI for the service, with "/new_container/new_name" appended to it. "new_name" defaults to the original object's name, but if you supply a different name for the copied object, that one is used instead.
The headers contain an item "X-Copy-From", whose value is "/original_container/original_name", which tells the API where to copy from. The operation is a PUT. "COPY" is a non-standard method; I don't know what idiot wrote the documentation you cited. These are the HTTP methods: https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods
Hope that makes some sense. If not, please let me know what needs clarifying.
-- Ed Leafe
On May 12, 2022, at 14:06, Ed Leafe ed@leafe.com wrote:
nm = new_obj_name or utils.get_name(obj) uri = "/%s/%s" % (utils.get_name(new_container), nm) copy_from = "/%s/%s" % (utils.get_name(container), utils.get_name(obj)) headers = {"X-Copy-From": copy_from, "Content-Length": "0"} if content_type: headers["Content-Type"] = content_type resp, resp_body = self.api.method_put(uri, headers=headers) return resp.headers.get("etag")
Ugh, that totally messed the formatting. Who the hell runs this email list????
Here's the code as it should be: https://github.com/pycontribs/pyrax/blob/master/pyrax/object_storage.py#L599...
-- Ed Leafe
On May 12, 2022, at 14:31, Ed Leafe ed@leafe.com wrote:
Here's the code as it should be: https://github.com/pycontribs/pyrax/blob/master/pyrax/object_storage.py#L599...
Geez, that's just the handler code. Here's the actual call I copied in the first message: https://github.com/pycontribs/pyrax/blob/master/pyrax/object_storage.py#L144...
Gotta stop emailing while writing other code. :)
-- Ed Leafe
:) Thanks Ed. I'll let you know how I get on.
Frank.
Frank Cazabon
On 12/05/2022 3:33 pm, Ed Leafe wrote:
On May 12, 2022, at 14:31, Ed Leafe ed@leafe.com wrote:
Here's the code as it should be: https://github.com/pycontribs/pyrax/blob/master/pyrax/object_storage.py#L599...
Geez, that's just the handler code. Here's the actual call I copied in the first message: https://github.com/pycontribs/pyrax/blob/master/pyrax/object_storage.py#L144...
Gotta stop emailing while writing other code. :)
-- Ed Leafe
[excessive quoting removed by server]
Hi Ed,
unfortunately I'm not getting it to work (either from VFP or from Postman).
Here is what I have tried in VFP:
m.lcAccountNumber = "999999" && 6 digit customer number
m.lcSourceFile = "/PensionDocuments/0003598C-466F-9A42-1C5E-F38944279108.pdf" m.lcDestFile = "/FRANK-Test/pensions/0003598C-466F-9A42-1C5E-F38944279108.pdf"
m.lcBaseUrl = "https://ord.blockstorage.api.rackspacecloud.com/v1/" + m.lcAccountNumber
loXmlHttp.Open( "PUT" , m.lcBaseUrl + m.lcDestFile, .F. ) loXmlHttp.setRequestHeader("X-Auth-Token", m.lcToken) loXmlHttp.setRequestHeader("X-Copy-From", m.lcBaseUrl + m.lcSourceFile) loXmlHttp.setRequestHeader("Content-Length", 0) loXmlHttp.Send()
? "===================================" ? loXmlHttp.Status ? loXmlHttp.responsetext ? "==================================="
What I get back is: Status 404, the resource could not be found.
Can you see what I am doing wrong?
Frank.
Frank Cazabon
On 12/05/2022 3:06 pm, Ed Leafe wrote:
On May 12, 2022, at 13:10, Frank Cazabon frank.cazabon@gmail.com wrote:
anybody here ever had to do anything with Rackspace's Storage API to move objects around?
I think I've seen Rackspace mentioned here before so I'm hoping.
I've got to copy a file from one container to another (actually it's a lot of files but I'm just trying to prove the concept).
I wrote the Python SDK for Rackspace (actually, all of OpenStack), and here's the code for copying one object to another container:
@_handle_container_not_found def copy_object(self, container, obj, new_container, new_obj_name=None, content_type=None): """ Copies the object to the new container, optionally giving it a new name. If you copy to the same container, you must supply a different name. Returns the etag of the newly-copied object. You can optionally change the content_type of the object by supplying that in the 'content_type' parameter. """ nm = new_obj_name or utils.get_name(obj) uri = "/%s/%s" % (utils.get_name(new_container), nm) copy_from = "/%s/%s" % (utils.get_name(container), utils.get_name(obj)) headers = {"X-Copy-From": copy_from, "Content-Length": "0"} if content_type: headers["Content-Type"] = content_type resp, resp_body = self.api.method_put(uri, headers=headers) return resp.headers.get("etag")To translate to English, the URI is the base URI for the service, with "/new_container/new_name" appended to it. "new_name" defaults to the original object's name, but if you supply a different name for the copied object, that one is used instead.
The headers contain an item "X-Copy-From", whose value is "/original_container/original_name", which tells the API where to copy from. The operation is a PUT. "COPY" is a non-standard method; I don't know what idiot wrote the documentation you cited. These are the HTTP methods: https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods
Hope that makes some sense. If not, please let me know what needs clarifying.
-- Ed Leafe
[excessive quoting removed by server]
Where does m.lcToken come from?
On 13/05/2022 13:36, Frank Cazabon wrote:
Hi Ed,
unfortunately I'm not getting it to work (either from VFP or from Postman).
Here is what I have tried in VFP:
m.lcAccountNumber = "999999" && 6 digit customer number
m.lcSourceFile = "/PensionDocuments/0003598C-466F-9A42-1C5E-F38944279108.pdf" m.lcDestFile = "/FRANK-Test/pensions/0003598C-466F-9A42-1C5E-F38944279108.pdf"
m.lcBaseUrl = "https://ord.blockstorage.api.rackspacecloud.com/v1/" + m.lcAccountNumber
loXmlHttp.Open( "PUT" , m.lcBaseUrl + m.lcDestFile, .F. ) loXmlHttp.setRequestHeader("X-Auth-Token", m.lcToken) loXmlHttp.setRequestHeader("X-Copy-From", m.lcBaseUrl + m.lcSourceFile) loXmlHttp.setRequestHeader("Content-Length", 0) loXmlHttp.Send()
? "===================================" ? loXmlHttp.Status ? loXmlHttp.responsetext ? "==================================="
What I get back is: Status 404, the resource could not be found.
Can you see what I am doing wrong?
Frank.
Frank Cazabon
On 12/05/2022 3:06 pm, Ed Leafe wrote:
On May 12, 2022, at 13:10, Frank Cazabon frank.cazabon@gmail.com wrote:
anybody here ever had to do anything with Rackspace's Storage API to move objects around?
I think I've seen Rackspace mentioned here before so I'm hoping.
I've got to copy a file from one container to another (actually it's a lot of files but I'm just trying to prove the concept).
I wrote the Python SDK for Rackspace (actually, all of OpenStack), and here's the code for copying one object to another container:
@_handle_container_not_found def copy_object(self, container, obj, new_container, new_obj_name=None, content_type=None): """ Copies the object to the new container, optionally giving it a new name. If you copy to the same container, you must supply a different name.
Returns the etag of the newly-copied object.
You can optionally change the content_type of the object by supplying that in the 'content_type' parameter. """ nm = new_obj_name or utils.get_name(obj) uri = "/%s/%s" % (utils.get_name(new_container), nm) copy_from = "/%s/%s" % (utils.get_name(container), utils.get_name(obj)) headers = {"X-Copy-From": copy_from, "Content-Length": "0"} if content_type: headers["Content-Type"] = content_type resp, resp_body = self.api.method_put(uri, headers=headers) return resp.headers.get("etag")
To translate to English, the URI is the base URI for the service, with "/new_container/new_name" appended to it. "new_name" defaults to the original object's name, but if you supply a different name for the copied object, that one is used instead.
The headers contain an item "X-Copy-From", whose value is "/original_container/original_name", which tells the API where to copy from. The operation is a PUT. "COPY" is a non-standard method; I don't know what idiot wrote the documentation you cited. These are the HTTP methods: https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods
Hope that makes some sense. If not, please let me know what needs clarifying.
-- Ed Leafe
[excessive quoting removed by server]
I pull it out from an earlier response used for authentication
Frank.
Frank Cazabon
On 13/05/2022 8:40 am, Paul Newton wrote:
Where does m.lcToken come from?
On 13/05/2022 13:36, Frank Cazabon wrote:
Hi Ed,
unfortunately I'm not getting it to work (either from VFP or from Postman).
Here is what I have tried in VFP:
m.lcAccountNumber = "999999" && 6 digit customer number
m.lcSourceFile = "/PensionDocuments/0003598C-466F-9A42-1C5E-F38944279108.pdf" m.lcDestFile = "/FRANK-Test/pensions/0003598C-466F-9A42-1C5E-F38944279108.pdf"
m.lcBaseUrl = "https://ord.blockstorage.api.rackspacecloud.com/v1/" + m.lcAccountNumber
loXmlHttp.Open( "PUT" , m.lcBaseUrl + m.lcDestFile, .F. ) loXmlHttp.setRequestHeader("X-Auth-Token", m.lcToken) loXmlHttp.setRequestHeader("X-Copy-From", m.lcBaseUrl + m.lcSourceFile) loXmlHttp.setRequestHeader("Content-Length", 0) loXmlHttp.Send()
? "===================================" ? loXmlHttp.Status ? loXmlHttp.responsetext ? "==================================="
What I get back is: Status 404, the resource could not be found.
Can you see what I am doing wrong?
Frank.
Frank Cazabon
On 12/05/2022 3:06 pm, Ed Leafe wrote:
On May 12, 2022, at 13:10, Frank Cazabon frank.cazabon@gmail.com wrote:
anybody here ever had to do anything with Rackspace's Storage API to move objects around?
I think I've seen Rackspace mentioned here before so I'm hoping.
I've got to copy a file from one container to another (actually it's a lot of files but I'm just trying to prove the concept).
I wrote the Python SDK for Rackspace (actually, all of OpenStack), and here's the code for copying one object to another container:
@_handle_container_not_found def copy_object(self, container, obj, new_container, new_obj_name=None, content_type=None): """ Copies the object to the new container, optionally giving it a new name. If you copy to the same container, you must supply a different name.
Returns the etag of the newly-copied object.
You can optionally change the content_type of the object by supplying that in the 'content_type' parameter. """ nm = new_obj_name or utils.get_name(obj) uri = "/%s/%s" % (utils.get_name(new_container), nm) copy_from = "/%s/%s" % (utils.get_name(container), utils.get_name(obj)) headers = {"X-Copy-From": copy_from, "Content-Length": "0"} if content_type: headers["Content-Type"] = content_type resp, resp_body = self.api.method_put(uri, headers=headers) return resp.headers.get("etag")
To translate to English, the URI is the base URI for the service, with "/new_container/new_name" appended to it. "new_name" defaults to the original object's name, but if you supply a different name for the copied object, that one is used instead.
The headers contain an item "X-Copy-From", whose value is "/original_container/original_name", which tells the API where to copy from. The operation is a PUT. "COPY" is a non-standard method; I don't know what idiot wrote the documentation you cited. These are the HTTP methods: https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods
Hope that makes some sense. If not, please let me know what needs clarifying.
-- Ed Leafe
[excessive quoting removed by server]
On May 13, 2022, at 07:36, Frank Cazabon frank.cazabon@gmail.com wrote:
What I get back is: Status 404, the resource could not be found.
Can you see what I am doing wrong?
Nothing jumps out at me.
There is a 'v2' version of the API - have you tried that?
-- Ed Leafe
I just tried it with no difference. I wonder if this has anything to do with user rights. While in the UI on rackspace I saw a message about not being able to upload files unless my admin was logged in. I'll get the client to logion and see.
Frank.
Frank Cazabon
On 13/05/2022 9:12 am, Ed Leafe wrote:
On May 13, 2022, at 07:36, Frank Cazabon frank.cazabon@gmail.com wrote:
What I get back is: Status 404, the resource could not be found.
Can you see what I am doing wrong?
Nothing jumps out at me.
There is a 'v2' version of the API - have you tried that?
-- Ed Leafe
[excessive quoting removed by server]
Ed, is there a C# SDK for doing this? Or maybe it's time to learn some python.
Frank.
Frank Cazabon
On 13/05/2022 9:12 am, Ed Leafe wrote:
On May 13, 2022, at 07:36, Frank Cazabon frank.cazabon@gmail.com wrote:
What I get back is: Status 404, the resource could not be found.
Can you see what I am doing wrong?
Nothing jumps out at me.
There is a 'v2' version of the API - have you tried that?
-- Ed Leafe
[excessive quoting removed by server]
On May 13, 2022, at 14:38, Frank Cazabon frank.cazabon@gmail.com wrote:
Ed, is there a C# SDK for doing this? Or maybe it's time to learn some python.
A long time ago there was, but I have no knowledge of its current state. I used to head of the team that developed SDKs for Python, Java, NodeJS, Ruby, C#, and PHP. But that was 8 years ago, and Rackspace isn't the same company now that they were then. They were bought by a vulture ^H^H^H^H^H^H venture capital firm several years ago, and they are a pale shadow of what they once were.
As an aside, I would consider moving resources to a different cloud provider. I haven't used Rackspace for any of my cloud needs for about 4 years now.
-- Ed Leafe
Thanks,
unfortunately I don't have much of a say regarding my client's use of Rackspace. They have another developer who seems familiar with the PHP SDK so I'm trying to get this person to do this work. I think they also cannot achieve what they want to do anyhow because their data does not allow them to. I've left them investigating this for now.
Frank.
Frank Cazabon
On 13/05/2022 4:01 pm, Ed Leafe wrote:
On May 13, 2022, at 14:38, Frank Cazabon frank.cazabon@gmail.com wrote:
Ed, is there a C# SDK for doing this? Or maybe it's time to learn some python.
A long time ago there was, but I have no knowledge of its current state. I used to head of the team that developed SDKs for Python, Java, NodeJS, Ruby, C#, and PHP. But that was 8 years ago, and Rackspace isn't the same company now that they were then. They were bought by a vulture ^H^H^H^H^H^H venture capital firm several years ago, and they are a pale shadow of what they once were.
As an aside, I would consider moving resources to a different cloud provider. I haven't used Rackspace for any of my cloud needs for about 4 years now.
-- Ed Leafe
[excessive quoting removed by server]
Actually - I believe the Big Kahuna here - Ed Leafe - he worked for RackSpace if I am not Mistaken!!!
On 5/12/2022 11:10 AM, Frank Cazabon wrote:
Hi,
anybody here ever had to do anything with Rackspace's Storage API to move objects around?
I think I've seen Rackspace mentioned here before so I'm hoping.
I've got to copy a file from one container to another (actually it's a lot of files but I'm just trying to prove the concept).
I've managed to get the authentication sorted out which was defined like this:
$ curl https://identity.api.rackspacecloud.com/v2.0/tokens%C2%A0 \ -X POST \ -d '{"auth":{"RAX-KSKEY:apiKeyCredentials":{"username":"yourUserName","apiKey":"$apiKey"}}}' \ -H "Content-type: application/json"
I was able to translate that like this:
m.lcUrl = "https://identity.api.rackspacecloud.com/v2.0/tokens"
TEXT TO lcAuthBody NOSHOW TEXTMERGE { "auth": { "RAX-KSKEY:apiKeyCredentials": { "username": "<<UserName>>", "apiKey": "<<APIKey>>" } } } ENDTEXT
LOCAL loXmlHttp AS Microsoft.XMLHTTP
loXmlHttp = Newobject( "Microsoft.XMLHTTP" ) loXmlHttp.Open( "POST" , m.lcUrl, .F. ) loXmlHttp.setRequestHeader("Content-Type","application/json") loXmlHttp.Send( m.lcAuthBody )
I can then pull the token out of the loXmlHttp.responsetext
Now I want to use this token to copy a file from one container to another.
The documentation here (https://docs.rackspace.com/docs/cloud-files/v1/storage-api-reference/object-... ) gives this example:
COPY /v1/account/sourceContainer/sourceObject HTTP/1.1 Host: storageURL X-Auth-Token: yourAuthToken Destination: /destinationContainer/destinationObject
I don't know how to interpret this to make an xmlhttp call.
- What is the url for the end point? I've got the account,
sourceContainer and sourceObject but not sure what comes before the /v1/
I'm unaware of a COPY type of Http request, so what should that be?
Even trying various things in PostMan aren't helping :(