cancel
Showing results for 
Search instead for 
Did you mean: 

ABAP Integration with FastAPI for File Uploads: Seeking Code Guidance

03-02-2024 2:11 PM
naveenkumarb142 Product and Topic Expert
2596 views 5 comments Go to solution
0 Likes
SAP Managed Tags
Labels
ABAPabap technicalcl_http_clientHTTPPOST
Subscribe

Problem Statement:

I am working on integrating an ABAP system with a FastAPI server to upload files via HTTP POST requests. I have a FastAPI endpoint set up to receive file uploads, and I need assistance with creating the ABAP code to send a file to this endpoint.

Description:

  1. FastAPI Endpoint: I have a FastAPI endpoint (POST /upload/) set up to receive file uploads. The endpoint expects the file to be included in the body of the request.

  2. ABAP System: On the ABAP side, I need to write code that reads a file from the filesystem and sends it to the FastAPI endpoint via an HTTP POST request.

Requirements:

  1. HTTP POST Request: The ABAP code should construct an HTTP POST request to the FastAPI endpoint.

  2. Multipart Form Data: The file should be sent as multipart form data in the body of the POST request.

    curl -X POST -F "[email protected]" https://endpoint.cfapps.us10-001.hana.ondemand.com/upload/ This curl works on vscode or command prompt. I want to achieve same from ABAP. 

    Server accepts data file containing JSON, does processing and returns JSON. Sever side is python.
    #if_http_client #abap #btp #httprequests #fileuploads #Post @Tomas_Buryanek I saw your answer for similar query on image upload to servicenow. Kindly help with this, seeking your expertise.

    Regards,
    Naveen
0 Likes

Accepted Solutions (1)

Accepted Solutions (1)

naveenkumarb142
Product and Topic Expert
Product and Topic Expert
0 Likes

REPORT ztest_030324.

CONSTANTS:
lc_content_type TYPE string VALUE 'Content-Type'.

DATA:
ls_desc TYPE soli,
lv_response TYPE string,
lt_data TYPE TABLE OF string,
ls_data TYPE string,
lv_data TYPE string,
lv_filename TYPE string VALUE 'C:\DUMMY\FILE.JSON',
lv_url TYPE string VALUE 'https://dummy-endpoint.com/upload/'.

* Data Declarations for http client.
DATA:
lo_http_client TYPE REF TO if_http_client,
lo_rest_client TYPE REF TO cl_rest_http_client.

* Data Declarations for http client header.
DATA:
lt_headers TYPE tihttpnvp,
ls_headers LIKE LINE OF lt_headers,
lo_request_part TYPE REF TO if_http_entity,
lv_content_disposition TYPE string.

* Get the current active screen as a screenshot.
CALL METHOD cl_gui_frontend_services=>gui_upload
EXPORTING
filename = lv_filename
CHANGING
data_tab = lt_data
EXCEPTIONS
access_denied = 1
error_no_gui = 3
not_supported_by_gui = 4
OTHERS = 5.

* Convert the table of strings to a single string.
LOOP AT lt_data INTO ls_data.
CONCATENATE lv_data ls_data INTO lv_data.
ENDLOOP.

DATA: lv_datax TYPE xstring.

CALL FUNCTION 'SCMS_STRING_TO_XSTRING'
EXPORTING
text = lv_data
IMPORTING
buffer = lv_datax
EXCEPTIONS
failed = 1
OTHERS = 2.
IF sy-subrc <> 0.
* Implement suitable error handling here
ENDIF.

cl_http_client=>create_by_url( EXPORTING url = lv_url IMPORTING client = lo_http_client ).
lo_http_client->request->set_header_field( name = 'Content-Type' value = 'multipart/form-data' ). "#EC NOTEXT
lo_request_part = lo_http_client->request->add_multipart( ).
lo_request_part->set_content_type( 'application/xml' ).
lv_content_disposition = |form-data; name="file"; filename="data.json" |.
lo_request_part->set_header_field( name = `Content-Disposition` value = lv_content_disposition ).
lo_request_part->set_data( data = lv_datax ).

* Set method as post method.
lo_http_client->request->set_method(
EXPORTING
method = if_http_entity=>co_request_method_post ).

lo_http_client->request->set_content_type(
EXPORTING
content_type = 'multipart/form-data'
).

* Prepare header of the API call.
CREATE OBJECT lo_rest_client
EXPORTING
io_http_client = lo_http_client.

ls_headers-name = lc_content_type.
ls_headers-value = 'application/json'.
APPEND ls_headers TO lt_headers.

CALL METHOD lo_rest_client->if_rest_client~set_request_headers
EXPORTING
it_header_fields = lt_headers.

* Send and receive the data to and from the dummy API endpoint.
lo_http_client->send(
EXCEPTIONS
http_communication_failure = 1
http_invalid_state = 2 ).

CHECK sy-subrc = 0.
lo_http_client->receive(
EXCEPTIONS
http_communication_failure = 1
http_invalid_state = 2
http_processing_failed = 3 ).

* Response manipulation to get the incident number.
lv_response = lo_http_client->response->get_cdata( ).

WRITE: / lv_response.

This is the ABAP code
Response -> Response.png

 

Andre_Fischer
Product and Topic Expert
Product and Topic Expert
0 Likes
if this is the solution, why don't you mark it as solved?
naveenkumarb142
Product and Topic Expert
Product and Topic Expert
0 Likes
Hi Andre,
naveenkumarb142
Product and Topic Expert
Product and Topic Expert
0 Likes
Hi Andre, This is not the solution, Its the code I am using and error am facing.

Answers (1)

Answers (1)

naveenkumarb142
Product and Topic Expert
Product and Topic Expert
0 Likes
DATA: lv_url TYPE string VALUE " ",      
      lo_http_client TYPE REF TO if_http_client,       
      lv_text        TYPE string,       
      lv_json_text   TYPE string,       
      lv_jsonx_text  TYPE xstring,       
      lv_jsonx       TYPE xstring,       
      lo_part        TYPE REF TO if_http_entity.  

*   Create XML reader     
DATA(lo_reader) = cl_sxml_string_reader=>create( cl_abap_codepage=>convert_to( iv_json ) ).     

TRY.         
lo_reader->next_node( ).         
lo_reader->skip_node( ).       
CATCH cx_sxml_parse_error INTO DATA(lx_parse_error).         cl_demo_output=>display( lx_parse_error->get_text( ) ).     
ENDTRY.  

*   Create HTTP client     
cl_http_client=>create_by_url( EXPORTING url = lv_url IMPORTING client = lo_http_client ).  

*   Prepare request    
lo_http_client->request->set_method( if_http_request=>co_request_method_post ).     
lo_http_client->request->set_content_type( 'multipart/form-data' ).     lo_http_client->request->set_form_field( name = 'File' value = 'data.json' ).     lo_http_client->request->set_form_field( name = 'Text' value = 'Cluster based on Customer' ).      
lv_text = to_lower( iv_bundle_criteria ).     
lv_json_text = '{"placeholder"}'.     
REPLACE 'placeholder' IN CHARACTER MODE  WITH lv_text INTO lv_json_text.     lv_jsonx_text  = cl_abap_codepage=>convert_to( source = lv_json_text codepage = 'UTF-8' ).     
DATA(json_lenx_text) = xstrlen( lv_jsonx_text ).      
lv_jsonx  = cl_abap_codepage=>convert_to( source = iv_json codepage = 'UTF-8' ).    
DATA(json_lenx) = xstrlen( lv_jsonx ).  

*   Add multipart form data - File Data     
lo_part = lo_http_client->request->if_http_entity~add_multipart( ).     lo_part->set_header_field( name = 'content-disposition' value = 'form-data; name="file"; filename="data.json"' ).     
lo_part->set_data( data = lv_jsonx offset = 0  length = json_lenx ). 

*   Add multipart form data - Text Data     
lo_part = lo_http_client->request->if_http_entity~add_multipart( ).     lo_part->set_header_field( name = 'content-disposition' value = 'form-data; name="text"; value="Cluster based on Customer"' ).     
lo_part->set_data( data = lv_jsonx_text offset = 0  length = json_lenx_text ).  

*   Send and receive data     
lo_http_client->send( EXCEPTIONS http_communication_failure = 1 http_invalid_state = 2 ).     
CHECK sy-subrc = 0.     
lo_http_client->receive( EXCEPTIONS http_communication_failure = 1 http_invalid_state = 2 http_processing_failed = 3 ).  

*   Response Data.     
rv_response = lo_http_client->response->get_cdata( ).