Skip to content

Commit 0155d89

Browse files
committed
docs: add Usage and README document
- add `Usage` document - improve `README.md` - adjust the source code docs in `src/`.
1 parent 250af30 commit 0155d89

File tree

10 files changed

+466
-135
lines changed

10 files changed

+466
-135
lines changed

README.md

+121-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,121 @@
1-
Documentation is coming, please use [API Reference](https://WSH032.github.io/fastapi-proxy-lib/) first. :smile:
1+
# FastAPI Proxy Lib
2+
3+
<p align="center">
4+
<em>HTTP/WebSocket proxy for starlette/FastAPI</em>
5+
</p>
6+
7+
| | |
8+
| ------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
9+
| CI/CD | [![CI: lint-test]][CI: lint-test#link] [![CI: docs]][CI: docs#link] |
10+
| Code | [![codecov]][codecov#link] [![Code style: black]][Code style: black#link] [![Ruff]][Ruff#link] [![Checked with pyright]][Checked with pyright#link] |
11+
| Package | [![Python-Version]][Python-Version#link] |
12+
| Meta | [![Hatch project]][Hatch project#link] [![GitHub License]][GitHub License#link] |
13+
14+
---
15+
16+
Documentation: <https://wsh032.github.io/fastapi-proxy-lib/>
17+
18+
Source Code: <https://github.com/WSH032/fastapi-proxy-lib/>
19+
20+
---
21+
22+
## Features
23+
24+
- [X] **Out of the box !** [Helper functions](#quick-start) to get FastAPI `app`/`router` for proxy conveniently.
25+
- [x] **Only `Starlette` is required** for it to work ([`FastAPI` is optional](#installation)).
26+
- [x] Support both **HTTP** and **WebSocket** proxy.
27+
- [x] Supports all HTTP methods (`GET`, `POST`, etc.)
28+
- [x] Support both **reverse** proxy and **forward** proxy.
29+
- [x] **Transparently** and **losslessly** handle all proxy requests,
30+
- [x] Asynchronous streaming transfer, support **file proxy**.
31+
32+
### other features
33+
34+
- [x] Strict linting and strict-mode Pyright type checking.
35+
- [x] **100%** [Type Completeness](https://microsoft.github.io/pyright/#/typed-libraries?id=type-completeness), [Code coverage of **over 95%**][codecov#link].
36+
- [x] Forced keep-alive connections, minimizing proxy latency.
37+
- [x] Handle errors as gracefully as possible.
38+
39+
### `FastAPI Proxy Lib` stands on the shoulders of giants
40+
41+
- [httpx](https://github.com/encode/httpx) for HTTP proxy
42+
- [httpx-ws](https://github.com/frankie567/httpx-ws) for WebSocket proxy
43+
44+
So, it perfectly supports all features of [httpx.AsyncClient](https://www.python-httpx.org/advanced/#client-instances), you can even use your custom `AsyncClient`, [`Transport`](https://www.python-httpx.org/advanced/#custom-transports).
45+
46+
## Installation
47+
48+
> !!! note
49+
>
50+
> We follow semantic versioning.<br>
51+
> This is a young project, and before 1.0.0, there may be changes in the API (though we try to avoid that).<br>
52+
> We recommend pinning to any minor versions, such as 0.1.x.
53+
54+
Pypi will come soon, please install from github temporarily:
55+
56+
```shell
57+
pip install fastapi-proxy-lib[standard]@git+https://github.com/WSH032/fastapi-proxy-lib.git
58+
```
59+
60+
Perhaps you've noticed that we're installing `fastapi-proxy-lib[standard]` instead of `fastapi-proxy-lib`. The difference is:
61+
62+
- The former will install `FastAPI` at the same time.
63+
- The latter installs only the basic dependencies for `fastapi-proxy-lib`.
64+
65+
If you **only need to use this library with Starlette**, you only need to install the latter.
66+
67+
## Quick start
68+
69+
With the helper functions, get the FastAPI proxy server app is very convenient and out of the box:
70+
71+
```python
72+
from fastapi_proxy_lib.fastapi.app import reverse_http_app
73+
74+
app = reverse_http_app(base_url="http://www.example.com/foo/")
75+
```
76+
77+
That's all! Now, you can launch the proxy server with `uvicorn`:
78+
79+
```shell
80+
uvicorn main:app --host 127.0.0.1 --port 8000
81+
```
82+
83+
Then, visit `http://127.0.0.1:8000/bar?baz=1`, you will get the response from `http://www.example.com/foo/bar?baz=1`.
84+
85+
For support with `FastAPI router` or only using `Starlette`, please **visit to our [documentation 📚](https://wsh032.github.io/fastapi-proxy-lib/) for more details**.
86+
87+
## development
88+
89+
- If you find any issues, please don't hesitate to [open an issue](https://github.com/WSH032/fastapi-proxy-lib/issues).
90+
- If you need assistance, feel free to [start a discussion](https://github.com/WSH032/fastapi-proxy-lib/discussions).
91+
- [Welcome PR](https://github.com/WSH032/fastapi-proxy-lib/pulls)
92+
93+
English is not the native language of the author (me), so if you find any areas for improvement in the documentation, your feedback is welcome.
94+
95+
If you think this project helpful, consider giving it a star ![GitHub Repo stars](https://img.shields.io/github/stars/wsh032/fastapi-proxy-lib?style=social)
96+
, which makes me happy. :smile:
97+
98+
## License
99+
100+
This project is licensed under the terms of the *Apache License 2.0*.
101+
102+
<!-- link -->
103+
104+
[CI: lint-test]: https://github.com/WSH032/fastapi-proxy-lib/actions/workflows/lint-test.yml/badge.svg?branch=main
105+
[CI: lint-test#link]: https://github.com/WSH032/fastapi-proxy-lib/actions/workflows/lint-test.yml
106+
[CI: docs]: https://github.com/WSH032/fastapi-proxy-lib/actions/workflows/docs.yml/badge.svg?branch=main
107+
[CI: docs#link]: https://github.com/WSH032/fastapi-proxy-lib/actions/workflows/docs.yml
108+
[Python-Version]: https://img.shields.io/python/required-version-toml?tomlFilePath=https%3A%2F%2Fraw.githubusercontent.com%2FWSH032%2Ffastapi-proxy%2Fmain%2Fpyproject.toml&logo=python&logoColor=gold&label=Python
109+
[Python-Version#link]: https://github.com/WSH032/fastapi-proxy-lib/blob/main/pyproject.toml
110+
[Code style: black]: https://img.shields.io/badge/code%20style-black-000000.svg
111+
[Code style: black#link]: https://github.com/psf/black
112+
[GitHub License]: https://img.shields.io/github/license/WSH032/fastapi-proxy-lib?color=9400d3
113+
[GitHub License#link]: https://github.com/WSH032/fastapi-proxy-lib/blob/main/LICENSE
114+
[Ruff]: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json
115+
[Ruff#link]: https://github.com/astral-sh/ruff
116+
[Checked with pyright]: https://microsoft.github.io/pyright/img/pyright_badge.svg
117+
[Checked with pyright#link]: https://microsoft.github.io/pyright
118+
[Hatch project]: https://img.shields.io/badge/%F0%9F%A5%9A-Hatch-4051b5.svg
119+
[Hatch project#link]: https://github.com/pypa/hatch
120+
[codecov]: https://codecov.io/gh/WSH032/fastapi-proxy-lib/graph/badge.svg?token=62QQU06E8X
121+
[codecov#link]: https://codecov.io/gh/WSH032/fastapi-proxy-lib

docs/Usage/Advanced-and-Starlette.md

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Advanced and Starlette
2+
3+
For the following scenarios, you might prefer [fastapi_proxy_lib.core][]:
4+
5+
- When you need to use proxies with **only** `Starlette` dependencies (without `FastAPI`).
6+
- When you need more fine-grained control over parameters and lifespan event.
7+
- When you need to further process the input and output before and after the proxy (similar to middleware).
8+
9+
We will demonstrate with `FastAPI`,
10+
but you can completely switch to the `Starlette` approach,
11+
which is officially supported by this project.
12+
13+
**^^[Please visit the `ReverseHttpProxy#examples` to view the demo with annotations :material-file-document: ][fastapi_proxy_lib.core.http.ReverseHttpProxy--examples]^^**.
14+
15+
Also (without annotations):
16+
17+
- [`ForwardHttpProxy#examples`][fastapi_proxy_lib.core.http.ForwardHttpProxy--examples]
18+
- [`ReverseWebSocketProxy#examples`][fastapi_proxy_lib.core.websocket.ReverseWebSocketProxy--examples]

docs/Usage/FastAPI-Helper.md

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# FastAPI Helper
2+
3+
!!!note
4+
FastAPI Helper Module need `FastAPI` installed.
5+
6+
There are two helper modules to get FastAPI `app`/`router` for proxy conveniently.
7+
8+
- [fastapi_proxy_lib.fastapi.app][]: High-level
9+
- [fastapi_proxy_lib.fastapi.router][]: Low-level
10+
11+
## app
12+
13+
use `fastapi_proxy_lib.fastapi.app` is very convenient and out of the box, there are three helper functions:
14+
15+
- [forward_http_app][fastapi_proxy_lib.fastapi.app.forward_http_app]
16+
- [reverse_http_app][fastapi_proxy_lib.fastapi.app.reverse_http_app]
17+
- [reverse_ws_app][fastapi_proxy_lib.fastapi.app.reverse_ws_app]
18+
19+
Example:
20+
21+
```python
22+
from fastapi_proxy_lib.fastapi.app import reverse_http_app
23+
from httpx import AsyncClient
24+
25+
client = AsyncClient() # (1)!
26+
base_url = "http://www.example.com/" # (2)!
27+
28+
app = reverse_http_app(client=client, base_url=base_url)
29+
```
30+
31+
1. You can pass `httpx.AsyncClient` instance:
32+
- if you want to customize the arguments, e.g. `httpx.AsyncClient(proxies={})`
33+
- if you want to reuse the connection pool of `httpx.AsyncClient`
34+
---
35+
Or you can pass `None`(The default value), then `fastapi-proxy-lib` will create a new `httpx.AsyncClient` instance for you.
36+
2. !!! note
37+
The `base_url` must end with `/`!
38+
39+
For other app helpers, please refer to their API references.
40+
41+
## router
42+
43+
For the following scenarios, you might prefer [fastapi_proxy_lib.fastapi.router][]:
44+
45+
- When you need to adjust the `app`/`router` parameters.
46+
- When you need to [mount the proxy on a route of larger app](https://fastapi.tiangolo.com/tutorial/bigger-applications/).
47+
48+
**^^[Please refer to the documentation of `RouterHelper` for more information :material-file-document: ][fastapi_proxy_lib.fastapi.router.RouterHelper--examples]^^**.

docs/Usage/Security.md

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Security
2+
3+
## proxy requests filter in forward proxy
4+
5+
Forward proxy allows access to any URL on input, which can be **scary** 😫 if not restricted.
6+
7+
For example, through `http://www.my-proxy-server.com/http://127.0.0.1:8000`,
8+
an attacker can access the server's local network.
9+
10+
So, there is a `proxy_filter` argument in [`ForwardHttpProxy`][fastapi_proxy_lib.core.http.ForwardHttpProxy.__init__] to filter requests.
11+
12+
If you do not explicitly specify it, `ForwardHttpProxy` will issue a warning and specify a [default_proxy_filter][fastapi_proxy_lib.core.tool.default_proxy_filter].
13+
14+
- If you want to accept all proxy requests (**never do this on a public server**), you can do it like this:
15+
16+
```python
17+
proxy_filter = lambda _: None
18+
```
19+
20+
- If you want to implement your own proxy filter, please refer to the [fastapi_proxy_lib.core.tool.ProxyFilterProto][].
21+
22+
## `http` vs `https`
23+
24+
!!! danger
25+
**Never use a server with the HTTPS protocol to proxy a target server (`base_url`) with the HTTP protocol !**
26+
27+
e.g. `https://www.my-proxy-server.com/http://www.example.com/`
28+
29+
There is a security issue:
30+
31+
Browsers may send sensitive HTTPS information to your HTTPS proxy server,
32+
then because of transparency feature, `fastapi-proxy-lib` will forward
33+
these information to the target server using the HTTP protocol without modification,
34+
which may cause privacy leaks.
35+
36+
!!! failure
37+
If you reverse it. Use an HTTP server to proxy an HTTPS target server.
38+
39+
There is a high probability that the request will fail.
40+
41+
## The same-origin policy of `ForwardHttpProxy`
42+
43+
The `ForwardHttpProxy` server uses the same source to proxy different target servers. e.g:
44+
45+
> http://www.my-proxy-server.com/http://www.example.com/<br>
46+
> http://www.my-proxy-server.com/http://www.google.com/
47+
>
48+
> both source are `http://www.my-proxy-server.com/`
49+
50+
For this situation, the browser's same-origin protection policy will fail,
51+
and cookies from `http://www.example.com/` will be sent to` http://www.google.com/`.
52+
53+
You should inform the user of this situation and let them decide whether to continue.

docs/Usage/index.md

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Introduction
2+
3+
We provide two types of proxies:
4+
5+
- reverse proxy:
6+
- [ReverseHttpProxy][fastapi_proxy_lib.core.http.ReverseHttpProxy]
7+
- [ReverseWebSocketProxy][fastapi_proxy_lib.core.websocket.ReverseWebSocketProxy]
8+
- forward proxy:
9+
- [ForwardHttpProxy][fastapi_proxy_lib.core.http.ForwardHttpProxy]
10+
11+
## What is a reverse proxy?
12+
13+
A reverse proxy is similar to a gateway.
14+
15+
All reverse proxies have a `base_url` parameter, which transparently forwards all requests sent to the proxy server to the target server specified by `base_url`.
16+
17+
For example, if you set `base_url` to `http://www.example.com/foo/`, and the proxy server launches at `http://127.0.0.1:8000`.
18+
19+
Then all requests sent to the proxy server will be forwarded to `http://www.example.com/foo/`, including `path-params`, `query-params`, `headers`, `cookies`, etc.
20+
21+
Visit `http//127.0.0.1:8000/bar?baz=1`, will get the response from `http://www.example.com/foo/bar?baz=1`.
22+
23+
## What is a forward proxy?
24+
25+
A forward proxy is very similar to a reverse proxy, except that the forward proxy server uses the full `path` of the requests it receives as the `base_url`.
26+
27+
For example, visit `http//127.0.0.1:8000/http://www.example.com/foo/bar?baz=1`, will get the response from `http://www.example.com/foo/bar?baz=1`.

mkdocs.yml

+8-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ theme:
2424
- content.action.view
2525
- content.tabs.link
2626
- content.tooltips
27-
# - navigation.top
27+
- navigation.top
2828
# - navigation.expand
2929
# - navigation.tracking
3030
# https://squidfunk.github.io/mkdocs-material/setup/changing-the-colors/#system-preference
@@ -124,6 +124,8 @@ extra:
124124

125125
watch:
126126
- src/fastapi_proxy_lib
127+
- README.md
128+
- CONTRIBUTING.md
127129

128130
validation:
129131
omitted_files: warn
@@ -134,4 +136,9 @@ validation:
134136
# It's used in scripts/gen_ref_pages.py
135137
nav:
136138
- Home: index.md
139+
- Usage:
140+
- Usage/index.md
141+
- Usage/FastAPI-Helper.md
142+
- Usage/Advanced-and-Starlette.md
143+
- Usage/Security.md
137144
- API Reference: reference/

0 commit comments

Comments
 (0)