fastcaddy


Namefastcaddy JSON
Version 0.0.2 PyPI version JSON
download
home_pagehttps://github.com/AnswerDotAI/fastcaddy
SummaryA simple python wrapper for using the Caddy API
upload_time2024-11-12 05:57:07
maintainerNone
docs_urlNone
authorJeremy Howard
requires_python>=3.7
licenseApache Software License 2.0
keywords nbdev jupyter notebook python
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # fastcaddy


<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->

## Usage

### Installation

Install from [pypi](https://pypi.org/project/fastcaddy/)

``` sh
$ pip install fastcaddy
```

## Installing Caddy

``` python
from fastcore.utils import *
```

This project is to help you use the caddy API, rather than a Caddyfile,
to use caddy. To use the API, you need to install a plugin for your
domain management service. We use Cloudflare, so we’ll document that
here. For other domain services, see the Caddy docs for other plugins.

### Cloudflare setup

You’ll need a token from Cloudflare with access to modify the necessary
settings. Here’s the steps to create a token with the minimal
privileges. You’ll need to install the cloudflare pip package, then
import:

``` python
from cloudflare import Cloudflare
```

Then you’ll need create a Cloudflare API token for your user, which
we’ll then use to create the less privileged token.

``` python
cf_token = os.environ['CLOUDFLARE_API_TOKEN']
```

We can now check that works OK:

``` python
cf = Cloudflare(api_token=cf_token)
zones = cf.zones.list()
len(zones.result)
```

    8

Replace this with your domain name:

``` python
domain = 'answer.ai'
zones = cf.zones.list(name=domain)
assert len(zones.result)==1
```

``` python
zone_id = zones.result[0].id
```

Here’s the methods available for modifying DNS records:

- `client.dns.records.create(*, zone_id, **params) -> Optional`
- `client.dns.records.update(dns_record_id, *, zone_id, **params) -> Optional`
- `client.dns.records.list(*, zone_id, **params) -> SyncV4PagePaginationArray[Record]`
- `client.dns.records.delete(dns_record_id, *, zone_id) -> Optional`
- `client.dns.records.edit(dns_record_id, *, zone_id, **params) -> Optional`
- `client.dns.records.export(*, zone_id) -> str`
- `client.dns.records.get(dns_record_id, *, zone_id) -> Optional`
- `client.dns.records.import\_(*, zone_id, **params) -> Optional`
- `client.dns.records.scan(*, zone_id, **params) -> Optional`

…and here’s the methods for tokens:

``` python
from cloudflare.types.user import (CIDRList, Policy, Token, TokenCreateResponse, TokenUpdateResponse, TokenListResponse,
                                   TokenDeleteResponse, TokenGetResponse, TokenVerifyResponse)
```

- `client.user.tokens.create(**params) -> Optional`
- `client.user.tokens.update(token_id, **params) -> object`
- `client.user.tokens.list(**params) -> SyncV4PagePaginationArray[object]`
- `client.user.tokens.delete(token_id) -> Optional`
- `client.user.tokens.get(token_id) -> object`
- `client.user.tokens.verify() -> Optional`

``` python
from cloudflare.types.user.tokens import PermissionGroupListResponse
```

- client.user.tokens.permission_groups.list() -\>
  SyncSinglePage\[object\]

``` python
from cloudflare.types.user.tokens import Value
```

- client.user.tokens.value.update(token_id, \*\*params) -\> str

We need these two permissions in our token:

``` python
permission_groups = cf.user.tokens.permission_groups.list()

dns_write = next(group for group in permission_groups if group['name'] == 'DNS Write')
zone_read = next(group for group in permission_groups if group['name'] == 'Zone Read')
```

Now we can create it:

``` python
new_token = cf.user.tokens.create(
    name='caddy_dns',
    policies=[{
        "effect": "allow",
        "resources": { f"com.cloudflare.api.account.zone.{zone_id}": "*" },
        "permission_groups": [
            {"id": zone_read['id'], "name": "Zone Read"},
            {"id": dns_write['id'], "name": "DNS Write"}
        ]
    }]
)

print(new_token.value)
```

Make a copy of this value, which we’ll need for setting up caddy.

### Installing caddy

To install caddy, we’ll use a tool called `xcaddy`. This is written in
go. So first install go:

- Mac: `brew install go`
- Linux: `sudo apt install golang`

Now we can install xcaddy:

``` sh
go install github.com/caddyserver/xcaddy/cmd/xcaddy@latest
```

Then we use that to compile caddy with our desired domain plugin
(cloudflare, in this case):

``` sh
cd ~/go/bin
./xcaddy build --with github.com/caddy-dns/cloudflare
```

This gives us a `~/go/bin/caddy` binary we can run:

``` sh
./caddy version
./caddy run
```

### Securely run caddy on start

If you’re using a server or running caddy a lot, you’ll want it to run
on start. And if you’re making it publicly accessible, you’ll want it to
be secure. This isn’t needed otherwise – you can just
`~/go/bin/caddy run` to run it manually (you may want to add `~/go/bin`
to your `PATH` env var).

To set this up, run from this repo root:

``` sh
./setup_service.sh
```

If all went well, you should see output like this:

``` sh
● caddy.service - Caddy
     Loaded: loaded (/etc/systemd/system/caddy.service; enabled; preset: enabled)
     Active: active (running) since Sat 2024-11-09 05:06:47 UTC; 2 days ago
       Docs: https://caddyserver.com/docs/
   Main PID: 138140 (caddy)
      Tasks: 29 (limit: 154166)
     Memory: 19.3M (peak: 28.8M)
        CPU: 3min 37.216s
     CGroup: /system.slice/caddy.service
             └─138140 /usr/bin/caddy run --environ
```

## How to use

We will now show how to set up caddy as a reverse proxy for hosts added
dynamically. We’ll grab our token from the previous step (assuming here
that it’s stored in an env var:

``` python
cf_token = os.environ.get('CADDY_CF_TOKEN', 'XXX')
```

We can now setup the basic routes needed for caddy:

``` python
setup_caddy(cf_token)
```

To view the configuration created, use
[`gcfg`](https://AnswerDotAI.github.io/fastcaddy/core.html#gcfg):

``` python
gcfg()
```

``` json
{ 'apps': { 'http': { 'servers': { 'srv0': { 'listen': [':80', ':443'],
                                             'routes': []}}},
            'tls': { 'automation': { 'policies': [{'issuers': [{'challenges': {'dns': {'provider': {'api_token': 'XXX', 'name': 'cloudflare'}}}, 'module': 'acme'}]}]}}}}
```

You can also view a sub-path of the configuration:

``` python
gcfg('/apps/http/servers')
```

``` json
{'srv0': {'listen': [':80', ':443'], 'routes': []}}
```

To add a reverse proxy, use
[`add_reverse_proxy`](https://AnswerDotAI.github.io/fastcaddy/core.html#add_reverse_proxy):

``` python
host = 'jph.answer.ai'
add_reverse_proxy(host, 'localhost:5001')
```

This is automatically added with an id matching the host, which you can
view with
[`gid`](https://AnswerDotAI.github.io/fastcaddy/core.html#gid):

``` python
gid('jph.answer.ai')
```

``` json
{ '@id': 'jph.answer.ai',
  'handle': [{'handler': 'reverse_proxy', 'upstreams': [{'dial': 'localhost:5001'}]}],
  'match': [{'host': ['jph.answer.ai']}],
  'terminal': True}
```

If you call this again with the same host, it will be replaced:

``` python
add_reverse_proxy(host, 'localhost:8000')
gid('jph.answer.ai').handle[0]
```

``` json
{'handler': 'reverse_proxy', 'upstreams': [{'dial': 'localhost:8000'}]}
```

To remove a host, delete its id:

``` python
del_id(host)
```

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/AnswerDotAI/fastcaddy",
    "name": "fastcaddy",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.7",
    "maintainer_email": null,
    "keywords": "nbdev jupyter notebook python",
    "author": "Jeremy Howard",
    "author_email": "github@jhoward.fastmail.fm",
    "download_url": "https://files.pythonhosted.org/packages/71/bf/3d1e9c5a2562dde131eacdd48d15f6cb6b217972b48dde68b17b67c2f771/fastcaddy-0.0.2.tar.gz",
    "platform": null,
    "description": "# fastcaddy\n\n\n<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->\n\n## Usage\n\n### Installation\n\nInstall from [pypi](https://pypi.org/project/fastcaddy/)\n\n``` sh\n$ pip install fastcaddy\n```\n\n## Installing Caddy\n\n``` python\nfrom fastcore.utils import *\n```\n\nThis project is to help you use the caddy API, rather than a Caddyfile,\nto use caddy. To use the API, you need to install a plugin for your\ndomain management service. We use Cloudflare, so we\u2019ll document that\nhere. For other domain services, see the Caddy docs for other plugins.\n\n### Cloudflare setup\n\nYou\u2019ll need a token from Cloudflare with access to modify the necessary\nsettings. Here\u2019s the steps to create a token with the minimal\nprivileges. You\u2019ll need to install the cloudflare pip package, then\nimport:\n\n``` python\nfrom cloudflare import Cloudflare\n```\n\nThen you\u2019ll need create a Cloudflare API token for your user, which\nwe\u2019ll then use to create the less privileged token.\n\n``` python\ncf_token = os.environ['CLOUDFLARE_API_TOKEN']\n```\n\nWe can now check that works OK:\n\n``` python\ncf = Cloudflare(api_token=cf_token)\nzones = cf.zones.list()\nlen(zones.result)\n```\n\n    8\n\nReplace this with your domain name:\n\n``` python\ndomain = 'answer.ai'\nzones = cf.zones.list(name=domain)\nassert len(zones.result)==1\n```\n\n``` python\nzone_id = zones.result[0].id\n```\n\nHere\u2019s the methods available for modifying DNS records:\n\n- `client.dns.records.create(*, zone_id, **params) -> Optional`\n- `client.dns.records.update(dns_record_id, *, zone_id, **params) -> Optional`\n- `client.dns.records.list(*, zone_id, **params) -> SyncV4PagePaginationArray[Record]`\n- `client.dns.records.delete(dns_record_id, *, zone_id) -> Optional`\n- `client.dns.records.edit(dns_record_id, *, zone_id, **params) -> Optional`\n- `client.dns.records.export(*, zone_id) -> str`\n- `client.dns.records.get(dns_record_id, *, zone_id) -> Optional`\n- `client.dns.records.import\\_(*, zone_id, **params) -> Optional`\n- `client.dns.records.scan(*, zone_id, **params) -> Optional`\n\n\u2026and here\u2019s the methods for tokens:\n\n``` python\nfrom cloudflare.types.user import (CIDRList, Policy, Token, TokenCreateResponse, TokenUpdateResponse, TokenListResponse,\n                                   TokenDeleteResponse, TokenGetResponse, TokenVerifyResponse)\n```\n\n- `client.user.tokens.create(**params) -> Optional`\n- `client.user.tokens.update(token_id, **params) -> object`\n- `client.user.tokens.list(**params) -> SyncV4PagePaginationArray[object]`\n- `client.user.tokens.delete(token_id) -> Optional`\n- `client.user.tokens.get(token_id) -> object`\n- `client.user.tokens.verify() -> Optional`\n\n``` python\nfrom cloudflare.types.user.tokens import PermissionGroupListResponse\n```\n\n- client.user.tokens.permission_groups.list() -\\>\n  SyncSinglePage\\[object\\]\n\n``` python\nfrom cloudflare.types.user.tokens import Value\n```\n\n- client.user.tokens.value.update(token_id, \\*\\*params) -\\> str\n\nWe need these two permissions in our token:\n\n``` python\npermission_groups = cf.user.tokens.permission_groups.list()\n\ndns_write = next(group for group in permission_groups if group['name'] == 'DNS Write')\nzone_read = next(group for group in permission_groups if group['name'] == 'Zone Read')\n```\n\nNow we can create it:\n\n``` python\nnew_token = cf.user.tokens.create(\n    name='caddy_dns',\n    policies=[{\n        \"effect\": \"allow\",\n        \"resources\": { f\"com.cloudflare.api.account.zone.{zone_id}\": \"*\" },\n        \"permission_groups\": [\n            {\"id\": zone_read['id'], \"name\": \"Zone Read\"},\n            {\"id\": dns_write['id'], \"name\": \"DNS Write\"}\n        ]\n    }]\n)\n\nprint(new_token.value)\n```\n\nMake a copy of this value, which we\u2019ll need for setting up caddy.\n\n### Installing caddy\n\nTo install caddy, we\u2019ll use a tool called `xcaddy`. This is written in\ngo. So first install go:\n\n- Mac: `brew install go`\n- Linux: `sudo apt install golang`\n\nNow we can install xcaddy:\n\n``` sh\ngo install github.com/caddyserver/xcaddy/cmd/xcaddy@latest\n```\n\nThen we use that to compile caddy with our desired domain plugin\n(cloudflare, in this case):\n\n``` sh\ncd ~/go/bin\n./xcaddy build --with github.com/caddy-dns/cloudflare\n```\n\nThis gives us a `~/go/bin/caddy` binary we can run:\n\n``` sh\n./caddy version\n./caddy run\n```\n\n### Securely run caddy on start\n\nIf you\u2019re using a server or running caddy a lot, you\u2019ll want it to run\non start. And if you\u2019re making it publicly accessible, you\u2019ll want it to\nbe secure. This isn\u2019t needed otherwise \u2013 you can just\n`~/go/bin/caddy run` to run it manually (you may want to add `~/go/bin`\nto your `PATH` env var).\n\nTo set this up, run from this repo root:\n\n``` sh\n./setup_service.sh\n```\n\nIf all went well, you should see output like this:\n\n``` sh\n\u25cf caddy.service - Caddy\n     Loaded: loaded (/etc/systemd/system/caddy.service; enabled; preset: enabled)\n     Active: active (running) since Sat 2024-11-09 05:06:47 UTC; 2 days ago\n       Docs: https://caddyserver.com/docs/\n   Main PID: 138140 (caddy)\n      Tasks: 29 (limit: 154166)\n     Memory: 19.3M (peak: 28.8M)\n        CPU: 3min 37.216s\n     CGroup: /system.slice/caddy.service\n             \u2514\u2500138140 /usr/bin/caddy run --environ\n```\n\n## How to use\n\nWe will now show how to set up caddy as a reverse proxy for hosts added\ndynamically. We\u2019ll grab our token from the previous step (assuming here\nthat it\u2019s stored in an env var:\n\n``` python\ncf_token = os.environ.get('CADDY_CF_TOKEN', 'XXX')\n```\n\nWe can now setup the basic routes needed for caddy:\n\n``` python\nsetup_caddy(cf_token)\n```\n\nTo view the configuration created, use\n[`gcfg`](https://AnswerDotAI.github.io/fastcaddy/core.html#gcfg):\n\n``` python\ngcfg()\n```\n\n``` json\n{ 'apps': { 'http': { 'servers': { 'srv0': { 'listen': [':80', ':443'],\n                                             'routes': []}}},\n            'tls': { 'automation': { 'policies': [{'issuers': [{'challenges': {'dns': {'provider': {'api_token': 'XXX', 'name': 'cloudflare'}}}, 'module': 'acme'}]}]}}}}\n```\n\nYou can also view a sub-path of the configuration:\n\n``` python\ngcfg('/apps/http/servers')\n```\n\n``` json\n{'srv0': {'listen': [':80', ':443'], 'routes': []}}\n```\n\nTo add a reverse proxy, use\n[`add_reverse_proxy`](https://AnswerDotAI.github.io/fastcaddy/core.html#add_reverse_proxy):\n\n``` python\nhost = 'jph.answer.ai'\nadd_reverse_proxy(host, 'localhost:5001')\n```\n\nThis is automatically added with an id matching the host, which you can\nview with\n[`gid`](https://AnswerDotAI.github.io/fastcaddy/core.html#gid):\n\n``` python\ngid('jph.answer.ai')\n```\n\n``` json\n{ '@id': 'jph.answer.ai',\n  'handle': [{'handler': 'reverse_proxy', 'upstreams': [{'dial': 'localhost:5001'}]}],\n  'match': [{'host': ['jph.answer.ai']}],\n  'terminal': True}\n```\n\nIf you call this again with the same host, it will be replaced:\n\n``` python\nadd_reverse_proxy(host, 'localhost:8000')\ngid('jph.answer.ai').handle[0]\n```\n\n``` json\n{'handler': 'reverse_proxy', 'upstreams': [{'dial': 'localhost:8000'}]}\n```\n\nTo remove a host, delete its id:\n\n``` python\ndel_id(host)\n```\n",
    "bugtrack_url": null,
    "license": "Apache Software License 2.0",
    "summary": "A simple python wrapper for using the Caddy API",
    "version": "0.0.2",
    "project_urls": {
        "Homepage": "https://github.com/AnswerDotAI/fastcaddy"
    },
    "split_keywords": [
        "nbdev",
        "jupyter",
        "notebook",
        "python"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "eace4072f8a62884eee999b3d671277cd6f40dd74d41470f53324332f755168c",
                "md5": "769fd31429d847a459c57f42e355795b",
                "sha256": "7daa96323374f5c740773e6fad13743142b964ccef75c91b1a0be302fecdbc1d"
            },
            "downloads": -1,
            "filename": "fastcaddy-0.0.2-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "769fd31429d847a459c57f42e355795b",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 10846,
            "upload_time": "2024-11-12T05:57:05",
            "upload_time_iso_8601": "2024-11-12T05:57:05.536095Z",
            "url": "https://files.pythonhosted.org/packages/ea/ce/4072f8a62884eee999b3d671277cd6f40dd74d41470f53324332f755168c/fastcaddy-0.0.2-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "71bf3d1e9c5a2562dde131eacdd48d15f6cb6b217972b48dde68b17b67c2f771",
                "md5": "591db5147020b23576cee285aff912f0",
                "sha256": "4430085fb1f96409dfe21f6ff420228080f65f97bcb8c6dd0e9b6e43d1485b68"
            },
            "downloads": -1,
            "filename": "fastcaddy-0.0.2.tar.gz",
            "has_sig": false,
            "md5_digest": "591db5147020b23576cee285aff912f0",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7",
            "size": 11996,
            "upload_time": "2024-11-12T05:57:07",
            "upload_time_iso_8601": "2024-11-12T05:57:07.244205Z",
            "url": "https://files.pythonhosted.org/packages/71/bf/3d1e9c5a2562dde131eacdd48d15f6cb6b217972b48dde68b17b67c2f771/fastcaddy-0.0.2.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-11-12 05:57:07",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "AnswerDotAI",
    "github_project": "fastcaddy",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "fastcaddy"
}
        
Elapsed time: 0.65236s