> For the complete documentation index, see [llms.txt](https://meetbill.gitbook.io/butterfly-project-doc/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://meetbill.gitbook.io/butterfly-project-doc/project-framework/how/api/funcattr/butterfly-file.md).

# (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)
