cancel
Showing results for 
Search instead for 
Did you mean: 

ABAP Integration with FastAPI for File Uploads: Seeking Code Guidance

naveenkumarb142
Product and Topic Expert
Product and Topic Expert
0 Kudos
954

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 "file=@data.json" 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

Accepted Solutions (1)

Accepted Solutions (1)

naveenkumarb142
Product and Topic Expert
Product and Topic Expert
0 Kudos

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 Kudos
if this is the solution, why don't you mark it as solved?
naveenkumarb142
Product and Topic Expert
Product and Topic Expert
0 Kudos
Hi Andre,
naveenkumarb142
Product and Topic Expert
Product and Topic Expert
0 Kudos
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 Kudos
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( ).