# (2) file

## HTTP 接口之文件处理 -- 上传与下载

* [1 文件下载](#1-文件下载)
* [2 文件上传](#2-文件上传)
* [传送门](#传送门)

## 1 文件下载

> 文件下载使用 protocol\_file.py

```
+ Protocol file--------------------------------+
|+ handler -----------------------------------+|
||file  :/handlers/{app}/__init__.py:{handler}||
||return:(stat_str, data_dict, headers_list)  ||
|+--------------------------------------------+|
| return:httpstatus, headers, content          |
+----------------------------------------------+

HTTP 请求方法:
    仅支持 GET 方法(仅用于获取文件)

HTTP 响应状态码及 Content-Type:
    HTTP 响应状态码:
        文件不存在时，HTTP 状态码为 404
        文件没读权限时，HTTP 状态码为 403
        检查参数错误时，HTTP 状态码为 400
        程序执行异常时，HTTP 状态码为 500
    HTTP 响应 Content-Type:
        文件 is_download 为 True 时，会根据文件后缀名进行识别文件类型
        文件 is_download 为 False 时，响应内容类型均为 ("Content-Type", "text/html")
```

> 例子

```python
from xlib.httpgateway import Request
from xlib import retstat
from xlib.middleware import funcattr

__info = "api_demo"
__version = "1.0.1"


@funcattr.api_download
def download(req):
    """
    Args:
        req             : (Object) Request
    Returns:
        stat_str, content_dict, headers_list
        > stat_str      : (String)
        > content_dict  : (Dict)
            filename    : (String) 文件路径
            is_download : (Bool) 是否需要下载
        > headers_list  : (List)
            key 和 value 都需要是 str 类型
    """
    isinstance(req, Request)
    return retstat.OK, {"filename": "test/static_file/test_html.html", "is_download": True}, [(__info, __version)]
```

## 2 文件上传

> 文件上传使用 protocol\_json.py

```
+ Protocol json--------------------------------+
|+ handler -----------------------------------+|
||file  :/handlers/{app}/__init__.py:{handler}||
||return:(stat_str, data_dict, headers_list)  ||
|+--------------------------------------------+|
| return:httpstatus, headers, content          |
+----------------------------------------------+

HTTP 请求方法

HTTP 响应状态码及 Content-Type:
    当需要序列化为 JSON 时, HTTP 状态码均为 200, 响应内容类型均为 ("Content-Type", "application/json"):
        检查参数错误时，返回 {"stat": "ERR_BAD_PARAMS"}
        程序执行异常时，返回 {"stat": "ERR_SERVER_EXCEPTION"}
```

> 例子

```python
from xlib.httpgateway import Request
from xlib import retstat
from xlib.middleware import funcattr

__info = "api_demo"
__version = "1.0.1"


@funcattr.api_upload
def upload(req):
    """
    
    """
    # 处理请求 body 
    return retstat.OK, {}, []
```

## 传送门

> * [HTTP Content-Type 及 Python mimetypes 库](https://github.com/meetbill/butterfly/wiki/Content-Type)
> * [如何流式读取数 G 超大文件](https://github.com/iswbm/magic-python/blob/master/source/c05/c05_06.md)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://meetbill.gitbook.io/butterfly-project-doc/project-framework/how/api/funcattr/butterfly-file.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
