# Docx Loader API

이 가이드는 DOC 및 DOCX 파일을 업로드하고 내용을 처리하여 결과를 반환하는 문서 처리 API의 사용 방법에 대해 설명합니다.

API의 주요 기능과 사용 방법을 간략하게 설명하며, 실제 사용 시에는 상세한 API 문서(Swagger)를 참조하는 것이 좋습니다.

> API TEST 사이트 주소 :  http://20.39.188.204:8000/

> 스웨거 주소: http://20.39.188.204:8000/docs 

## API 개요

버전: 1.0.0
OpenAPI 스펙: OAS 3.1
엔드포인트 기본 경로: /openapi.json
엔드포인트 및 기능

## 
루트 페이지 읽기 (GET /)

### 1. 사용자가 웹 페이지에 접속했을 때, 파일 업로드 페이지를 렌더링합니다.

- 방법: GET

- URL: **[http://20.39.188.204:8000/](http://20.39.188.204:8000/)**

- 응답: text/html

- 설명: 포함된 HTML 페이지는 파일 업로드 폼을 제공합니다.

## 파일 업로드 처리 (POST /upload/)

### 1. 업로드된 DOC 또는 DOCX 파일을 받아 백그라운드에서 처리를 시작합니다.

- 방법: POST

- URL: /upload/

- 요청 바디: multipart/form-data 형식, 파일 포함

- 응답: application/json

- 성공 응답 예시:

```
{
  "task_id": "654e9bf7-816e-4ea2-be2a-a04adcdf13af",
  "message": "File processing started. Visit /result/{task_id} for results."
}
```

### 예제 파일 입니다 (키는 별도 전달해 드립니다.)

upload.html

## 파일 처리 결과 조회 (GET /result/{task_id})

### 1. 업로드 및 처리된 파일의 결과를 조회합니다.

result.html

```
<!doctype html>
<html lang="en">
<head>
  <title>Document Analysis Results</title>
</head>
<body>
  <h1>Document Analysis Results</h1>
  <p>FileName: {{ file_name }}</p>
  <p>Total Pages: {{ page_count }}</p>
  <p>Elapsed Time: {{ elapsed_time }}</p>
  <p>Total TextArray count: {{ total_array_count }}</p>
  <h2>Page Texts:</h2>
  {% for item in page_texts %}
    <p><b>Page {{ item.page_number }}:</b> {{ item.text }}</p>
  {% endfor %}
</body>
</html>
```

- 방법: GET

- URL: /result/{task_id}

- 파라미터: task_id (문자열, 경로 변수)

- 응답: application/json

- 성공 응답 예시:

```
<p><b>Page 1:</b> (목  차)</p>

<p><b>Page 1:</b> 제1장 총칙                                 제 1 조 [목적]</p>

<p><b>Page 1:</b> 제 2 조 [적용범위]</p>

<p><b>Page 1:</b> 제 3 조 [사원의 정의]</p>

<p><b>Page 1:</b> 제2장 인사         제1절 통칙              제 4 조 [채용 조건]</p>

<p><b>Page 1:</b> 제 5 조 [채용 고시]</p>

<p><b>Page 1:</b> 제 6 조 [계열/직계/직급의 구분]</p>

<p><b>Page 1:</b> 제 6 조의 2 [2000. 1. 1.  삭제]</p>
```

## 작업 상태 조회 (GET /status/{task_id})

### 1. 처리 작업의 현재 상태를 확인할 수 있습니다. 

### 2. 주기적 호출을 통해 "completed" 상태가 되면 배열로 결과를 리턴합니다.

- 방법: GET

- URL: /status/{task_id}

- 파라미터: task_id (문자열, 경로 변수)

- 응답: application/json

- 성공 응답 예시:

```
{
  "status": "processing",
  "result": null,
  "start_time": "2024-06-04T08:54:17.886368",
  "elapsed_time": "0:01:20.500081"
}
```

- 완료시

```
{
  "status": "completed",
  "start_time": "2024-06-04T08:54:17.902006",
  "elapsed_time": "0:02:29.578560",
  "result": {
    "file_name": "1. 취업규칙.docx",
    "start_time": "2024-06-04T08:54:17.902006",
    "elapsed_time": "0:01:37.797150",
    "contents": [
      {
        "text": "(목  차)",
        "page_number": 1
      },
      {
        "text": "제1장 총칙                                 제 1 조 [목적]",
        "page_number": 1
      },
      {
        "text": "제 2 조 [적용범위]",
        "page_number": 1
      },

{

...................

},

}
```

## 인증 처리

IP 등록을 이용하여 처리함으로 현재 인증처리는 없습니다

## 오류 처리

### 1. 모든 엔드포인트는 유효성 검사 오류가 발생할 경우 HTTP 상태 코드 422와 함께 오류 세부정보를 반환할 수 있습니다.

- 응답: application/json

- 오류 응답 예시:

```
{
  "detail": [
    {
      "loc": ["body", 0],
      "msg": "파일이 필요합니다.",
      "type": "value_error.missing"
    }
  ]
}
```

## **API 호출 순서**

### 1. 파일 업로드 처리 (POST /upload/)

### 2. 작업 상태 조회 (GET /status/{task_id}) 주기적 호출 (3초~5초)

       작업 상태 조회 (GET /status/{task_id})

       작업 상태 조회 (GET /status/{task_id})

"status": "completed" 변경 되면서 결과 값을 배열로 리턴 합니다.

( 완료가 되면 GET /status/{task_id} 또는  GET /result/{task_id} 한번 더 호출해서 에서 값을 가져 가시거나 편리한 방법으로 사용 하시면 되고 현재는 둘다 데이타를 리턴 하고 있습니다. 리턴 형태 및 API 사용애 관한 수정 사항은 피드백 주시면 감사하겠습니다)

# 호출예제

## Python 

```
import requests

url = 'http://20.39.188.204:8000/upload/'
files = {'file': open('yourfile.docx', 'rb')}
headers = {'access_token': '7f53a88b-b3d0-4a97-911b-xxxxxxx'}

response = requests.post(url, files=files, headers=headers)
print(response.text)
```

## cURL

```
curl -X POST http://20.39.188.204:8000/upload/ 
    -H "access_token: 7f53a88b-b3d0-4a97-911b-xxxxxxx" 
    -F "file=@/path/to/yourfile.docx"
```

## JavaScript

```
const axios = require('axios');
const FormData = require('form-data');
const fs = require('fs');

const form = new FormData();
form.append('file', fs.createReadStream('/path/to/yourfile.docx'));

axios.post('http://20.39.188.204:8000/upload/', form, {
    headers: {
        ...form.getHeaders(),
        'access_token': '7f53a88b-b3d0-4a97-911b-xxxxxxxxx'
    }
}).then(response => {
    console.log(response.data);
}).catch(error => {
    console.error('Upload failed:', error.response.data);
});
```

## Java (Apache HttpClient 사용)

```
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.content.FileBody;

import java.io.File;

public class FileUploader {
    public static void main(String[] args) throws IOException {
        CloseableHttpClient client = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost("http://20.39.188.204:8000/upload/");

        File file = new File("/path/to/yourfile.docx");
        FileBody fileBody = new FileBody(file, ContentType.DEFAULT_BINARY);
    
        MultipartEntityBuilder builder = MultipartEntityBuilder.create();
        builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
        builder.addPart("file", fileBody);
        httpPost.setEntity(builder.build());
    
        httpPost.setHeader("access_token", "7f53a88b-b3d0-4a97-911b-xxxxxxx");
    
        CloseableHttpResponse response = client.execute(httpPost);
        try {
            System.out.println(EntityUtils.toString(response.getEntity()));
        } finally {
            response.close();
        }
    }

}
```

## CSharp

```
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using System.IO;

class Program
{
    static async Task Main(string[] args)
    {
        var filePath = @"C:\path\to\your\file.docx"; // 파일 경로 지정
        var url = "http://20.39.188.204:8000/upload/"; // 서버의 URL
        var apiKey = "YOUR_ACCESS_TOKEN"; // API 키 값

        using (var client = new HttpClient())
        {
            using (var content = new MultipartFormDataContent())
            {
                // 파일을 멀티파트 폼 데이터로 추가
                var fileContent = new ByteArrayContent(File.ReadAllBytes(filePath));
                fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
                {
                    Name = "\"file\"",
                    FileName = "\"" + Path.GetFileName(filePath) + "\""
                };
                fileContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
                content.Add(fileContent);

                // API 키를 요청 헤더에 추가
                client.DefaultRequestHeaders.Add("access_token", apiKey);

                try
                {
                    // 요청 보내기
                    HttpResponseMessage response = await client.PostAsync(url, content);
                    if (response.IsSuccessStatusCode)
                    {
                        string responseBody = await response.Content.ReadAsStringAsync();
                        Console.WriteLine("Response Body: " + responseBody);
                    }
                    else
                    {
                        Console.WriteLine("Failed to upload. Status code: " + response.StatusCode);
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Exception caught: " + ex.ToString());
                }
            }
        }
    }
}
```

> !! 문서 내 표 (보이는표 /안 보이는표) 나 텍스트박스가 많으면 더 느리게 처리됩니다. 

> !! 워드 문서 작성 방식에 따라서 
> 
> 표가 있는 문서의 경우 
> 1. 텍스트 페이지와 함께 표가 들어가는 경우 
> 2. 텍스트 페이지 추출 후, contents 배열 끝쪽에 해당 표와 페이지 번호가 들어가는 경우
> 
> 즉, 사용시 페이지 번호를 체크하여 사용하세요!

## 문의 하기

: contact@veluga.io

For the site tree, see the [root Markdown](https://slashpage.com/veluga-api.md).
