Creating projects and uploading files using curl

Hello,

We are testing GroupShare's Project Server capabilities in different automation/integration scenarios. As a business requirement, we need a mechanism to send data from our project management system to GS REST API using Linux command line. Usually we use curl for such tasks and it would be optimal if we managed to send project creation and file upload requests with curl as well. Following the instructions in  How to create a GroupShare project using Swagger UI and  How to upload files to an existing GS Project , I can create a project using Swagger UI and upload files with Postman without issues, but would like to know how to perform the same actions with curl. 

I can successfully create a project with a following curl request (real IDs replaced with dummy values)

curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' --header 'Authorization: Bearer <token>' -d '{"Name":"GSAPITest1","OrganizationId":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx","Description":"","ProjectTemplateId":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx","DueDate":"2024-11-30T09:49:09.186Z","ReferenceProjects":[{"ReferenceProjectId":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx","IsLocked":true,"ReferenceProjectName":"string"}],"SuppressEmail":true,"IsSecure":false}' 'groupsharedev.sdlproducts.com/.../projects'

and get a project ID as a response, but when trying to upload a file (.zip archive), there is no response. For example, if I run the following curl command

curl -v -X POST --header 'Accept: application/zip' --header 'Authorization: Bearer <token>' -F '=@"/path/to/the/Test.zip"' 'groupsharedev.sdlproducts.com/.../upload'

I get following results when using the --verbose option:

Note: Unnecessary use of -X or --request, POST is already inferred.
* Host groupsharedev.sdlproducts.com:443 was resolved.
* IPv6: (none)
* IPv4: 3.127.110.122, 3.77.248.104
* Trying 3.127.110.122:443...
* Connected to groupsharedev.sdlproducts.com (3.127.110.122) port 443
* ALPN: curl offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* CAfile: /etc/ssl/certs/ca-certificates.crt
* CApath: /etc/ssl/certs
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_128_GCM_SHA256 / X25519 / RSASSA-PSS
* ALPN: server accepted h2
* Server certificate:
* subject: CN=*.sdlproducts.com
* start date: Sep 22 00:00:00 2024 GMT
* expire date: Oct 21 23:59:59 2025 GMT
* subjectAltName: host "groupsharedev.sdlproducts.com" matched cert's "*.sdlproducts.com"
* issuer: C=US; O=Amazon; CN=Amazon RSA 2048 M02
* SSL certificate verify ok.
* Certificate level 0: Public key type RSA (2048/112 Bits/secBits), signed using sha256WithRSAEncryption
* Certificate level 1: Public key type RSA (2048/112 Bits/secBits), signed using sha256WithRSAEncryption
* Certificate level 2: Public key type RSA (2048/112 Bits/secBits), signed using sha256WithRSAEncryption
* using HTTP/2
* [HTTP/2] [1] OPENED stream for groupsharedev.sdlproducts.com/.../upload
* [HTTP/2] [1] [:method: POST]
* [HTTP/2] [1] [:scheme: https]
* [HTTP/2] [1] [:authority: groupsharedev.sdlproducts.com]
* [HTTP/2] [1] [:path: /api/projectserver/v2/projects/<projectId>/files/upload]
* [HTTP/2] [1] [user-agent: curl/8.5.0]
* [HTTP/2] [1] [accept: application/zip]
* [HTTP/2] [1] [authorization: Bearer <token>]
* [HTTP/2] [1] [content-length: 906]
* [HTTP/2] [1] [content-type: multipart/form-data; boundary=------------------------wgOoYrS3CQl5VHrRbpOuLW]
> POST /api/projectserver/v2/projects/<projectId>/files/upload HTTP/2
> Host: groupsharedev.sdlproducts.com
> User-Agent: curl/8.5.0
> Accept: application/zip
> Authorization: Bearer <token>
> Content-Length: 906
> Content-Type: multipart/form-data; boundary=------------------------wgOoYrS3CQl5VHrRbpOuLW
>
* We are completely uploaded and fine
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
< HTTP/2 200
< date: Wed, 30 Oct 2024 13:31:01 GMT
< content-length: 0
< server: Microsoft-IIS/10.0
< x-powered-by: ARR/3.0
< x-frame-options: SAMEORIGIN
< permissions-policy: clipboard-read=self, clipboard-write=self
< x-content-type-options: nosniff
< x-permitted-cross-domain-policies: none
< cross-origin-embedder-policy: require-corp
< cross-origin-opener-policy: same-origin
< cross-origin-resource-policy: same-origin
< referrer-policy: no-referrer
<
* Connection #0 to host groupsharedev.sdlproducts.com left intact

The response appears to me as okay, but the project does not appear when querying the https://groupsharedev.sdlproducts.com/api/projectserver/v2/projects endpoint. I've tried sending the same request with same information as parameters (create: true, reference:false and relativePath pointing to the actual URL-encoded file path), based on the documentation in Swagger UI, although relativePath is not required with .zip archives and reference is false and create is true by default.

If I repeat an upload request, the GS server responds with {"Message":"Adding Test.zip would result in duplicate files having the same name."}, so the file(s) are uploaded but project is not created. Am I just missing something essential which triggers project creation? Is there a way to get listing of projects which are registered for project creation, i.e. created by sending appropriate POST request to https://groupsharedev.sdlproducts.com/api/projectserver/v2/projects endpoint but which are not properly created by adding files?

I'd be grateful if someone could point out flaws in my curl requests or even point me to the right direction - or even suggest a solution. Slight smile

Best,
Mikko

  •  

    Hello Mikko,

    Thank you for reaching out and for providing detailed information about your workflow. From your message, it seems you’re almost there! To successfully create a project in GroupShare using curl, the full workflow involves three main steps:

    1. Create the Project: This is the initial project creation, which you've already done successfully. You’ll get a project ID in response, which you’ll need in the next steps.
    2. Upload the File: After creating the project, you successfully upload your file to the project.
    3. Finalize the Project Creation: After uploading the file, you need to make a POST request to the project creation endpoint. This step triggers the actual creation of the project, and it may take a moment for the project to be fully set up. Here’s the command to finalize the project creation:

    curl --location 
        --request POST 'https://groupsharedev.sdlproducts.com/api/projectserver/v2/projects/<project-id>/create' \
        --header 'Accept: application/json' \
        --header 'Content-Type: application/json' \
        --header 'Authorization: Bearer <token>'
    
     

    Replace <project-id> with the ID from your initial project creation response and ensure that <token> is replaced with your actual authorization token.

    Once these steps are completed, the project should be fully created in GroupShare.

    Additionally, keep in mind that there is a GroupShare PowerShell Toolkit, which also works with the REST API. This toolkit not only supports project creation but also implements further methods for managing users, translation memories, and other functionalities. It may streamline certain tasks or integrations if you prefer working within a PowerShell environment.

    Let me know if you encounter any further issues or need more clarification!

    Best Regards,

    Alexandru Florescu

  • Hi  ,

    Thank you for the support. I tried what you suggested and eventually got my curls working. Based on documentation in Swagger UI, a request to the /files/upload endpoint has the create=true parameter set by default, so that in cases where we wish to start project creation as soon as the first set of files is uploaded, we don't normally need to make an additional request to the /projects/<project-id>/create endpoint. But this is a good point, as we might wish to upload several sets of files with create=false as parameter and finish project creation separately.

    However, you managed to point us to the right track, as there was actually something wrong with the initial request to create an "empty" project. Removing the ReferenceProjects array from the JSON seemed to be the thing... I had just copied it over from the example available in Swagger UI and didn't review it. 

    curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' --header 'Authorization: Bearer <token>' -d '{"Name":"GSAPITest1","OrganizationId":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx","Description":"","ProjectTemplateId":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx","DueDate":"2024-11-30T09:49:09.186Z","SuppressEmail":true,"IsSecure":false}' 'groupsharedev.sdlproducts.com/.../projects'

    After the initial project was created without dummy reference project information, uploading the .zip archive triggered the project creation as expected and we're happy with the results.

    So thanks for your help!

    Best,
    Mikko