httpbinx 1.7.0__py3-none-any.whl → 1.8.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- httpbinx/__init__.py +1 -1
- httpbinx/constants.py +3 -5
- httpbinx/helpers.py +22 -6
- httpbinx/main.py +16 -5
- httpbinx/meta.py +42 -45
- httpbinx/routers/anything.py +46 -3
- httpbinx/routers/images.py +10 -13
- httpbinx/static/bombs/bomb-1GB.br +0 -0
- httpbinx/static/bombs/bomb-1GB.gz +0 -0
- {httpbinx-1.7.0.dist-info → httpbinx-1.8.1.dist-info}/METADATA +7 -3
- {httpbinx-1.7.0.dist-info → httpbinx-1.8.1.dist-info}/RECORD +14 -13
- {httpbinx-1.7.0.dist-info → httpbinx-1.8.1.dist-info}/WHEEL +1 -1
- httpbinx/utils.py +0 -15
- {httpbinx-1.7.0.dist-info → httpbinx-1.8.1.dist-info}/entry_points.txt +0 -0
- {httpbinx-1.7.0.dist-info → httpbinx-1.8.1.dist-info}/licenses/LICENSE +0 -0
httpbinx/__init__.py
CHANGED
httpbinx/constants.py
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
|
-
# flake8: noqa
|
3
1
|
REDIRECT_LOCATION = '/redirect/1'
|
4
2
|
|
5
3
|
ACCEPTED_MEDIA_TYPES = [
|
@@ -27,9 +25,9 @@ ASCII_ART = """
|
|
27
25
|
_...._
|
28
26
|
.' _ _ `.
|
29
27
|
| ."` ^ `". _,
|
30
|
-
|
28
|
+
\\_;`"---"`|//
|
31
29
|
| ;/
|
32
|
-
|
30
|
+
\\_ _/
|
33
31
|
`\"\"\"`
|
34
32
|
"""
|
35
33
|
|
@@ -40,7 +38,7 @@ ANGRY_ASCII = """
|
|
40
38
|
: :
|
41
39
|
| |
|
42
40
|
: __ :
|
43
|
-
|
41
|
+
\\ .-"` `"-. /
|
44
42
|
'. .'
|
45
43
|
'-......-'
|
46
44
|
YOU SHOULDN'T BE HERE
|
httpbinx/helpers.py
CHANGED
@@ -1,21 +1,23 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
1
|
import json
|
3
2
|
import random
|
4
3
|
import re
|
4
|
+
from pathlib import Path
|
5
5
|
|
6
6
|
from starlette import status
|
7
7
|
from starlette.requests import Request
|
8
8
|
from starlette.responses import Response
|
9
9
|
from starlette.templating import Jinja2Templates
|
10
10
|
|
11
|
-
from httpbinx.constants import ACCEPTED_MEDIA_TYPES
|
12
|
-
|
13
|
-
from httpbinx.
|
14
|
-
from httpbinx.schemas import RequestAttrs
|
15
|
-
from httpbinx.schemas import RequestInfo
|
11
|
+
from httpbinx.constants import (ACCEPTED_MEDIA_TYPES, ASCII_ART,
|
12
|
+
REDIRECT_LOCATION)
|
13
|
+
from httpbinx.schemas import RequestAttrs, RequestInfo
|
16
14
|
|
17
15
|
# init Jinja2
|
18
16
|
_templates = Jinja2Templates(directory='templates')
|
17
|
+
# image path
|
18
|
+
_images_path = Path(__file__).parent / 'static' / 'images'
|
19
|
+
# bomb files path
|
20
|
+
_bomb_files_path = Path(__file__).parent / 'static' / 'bombs'
|
19
21
|
|
20
22
|
|
21
23
|
def get_templates() -> Jinja2Templates:
|
@@ -23,6 +25,20 @@ def get_templates() -> Jinja2Templates:
|
|
23
25
|
return _templates
|
24
26
|
|
25
27
|
|
28
|
+
def get_images_path() -> Path:
|
29
|
+
"""Dependency function that returns the path to the images directory"""
|
30
|
+
if not _images_path.exists():
|
31
|
+
raise FileNotFoundError(f'{_images_path} does not exist.')
|
32
|
+
return _images_path
|
33
|
+
|
34
|
+
|
35
|
+
def get_bomb_file_path() -> Path:
|
36
|
+
"""Dependency function that returns the path to the bomb files directory"""
|
37
|
+
if not _bomb_files_path.exists():
|
38
|
+
raise FileNotFoundError(f'{_bomb_files_path} does not exist.')
|
39
|
+
return _bomb_files_path
|
40
|
+
|
41
|
+
|
26
42
|
async def to_request_info(request: Request, **extras) -> RequestInfo:
|
27
43
|
"""Returns model RequestInfo instance"""
|
28
44
|
await request.body() # Note: Execute `.stream()` only once.
|
httpbinx/main.py
CHANGED
@@ -1,9 +1,10 @@
|
|
1
|
-
from
|
1
|
+
from pathlib import Path
|
2
2
|
|
3
3
|
from fastapi import FastAPI
|
4
|
+
from fastapi.middleware.cors import CORSMiddleware
|
4
5
|
from fastapi.staticfiles import StaticFiles
|
5
6
|
|
6
|
-
from httpbinx.meta import
|
7
|
+
from httpbinx.meta import get_tags_metadata
|
7
8
|
from httpbinx.routers import router
|
8
9
|
|
9
10
|
app = FastAPI(
|
@@ -12,14 +13,24 @@ app = FastAPI(
|
|
12
13
|
'written in Python + FastAPI.',
|
13
14
|
docs_url='/', # swagger docs page url
|
14
15
|
swagger_ui_parameters={'docExpansion': 'none'},
|
15
|
-
openapi_tags=
|
16
|
+
openapi_tags=get_tags_metadata()
|
16
17
|
)
|
17
18
|
|
19
|
+
app.add_middleware(
|
20
|
+
CORSMiddleware,
|
21
|
+
allow_origins=['*'],
|
22
|
+
allow_credentials=True,
|
23
|
+
allow_methods=['*'],
|
24
|
+
allow_headers=['*'],
|
25
|
+
|
26
|
+
)
|
27
|
+
|
28
|
+
# mount static files
|
29
|
+
static_dir = Path(__file__).parent / 'static'
|
18
30
|
app.mount(
|
19
31
|
'/static',
|
20
|
-
StaticFiles(directory=
|
32
|
+
StaticFiles(directory=static_dir),
|
21
33
|
name='static'
|
22
34
|
)
|
23
35
|
|
24
|
-
# app.openapi_tags = []
|
25
36
|
app.include_router(router=router)
|
httpbinx/meta.py
CHANGED
@@ -1,45 +1,42 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
'
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
'
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
'description': 'Returns anything that is passed to request',
|
44
|
-
}
|
45
|
-
]
|
1
|
+
"""
|
2
|
+
This module defines the metadata for API tags used in the FastAPI application.
|
3
|
+
These tags are used to organize and categorize different endpoints in the API documentation.
|
4
|
+
"""
|
5
|
+
from functools import lru_cache
|
6
|
+
from typing import List
|
7
|
+
|
8
|
+
from pydantic import BaseModel, Field
|
9
|
+
|
10
|
+
|
11
|
+
class Tag(BaseModel):
|
12
|
+
name: str = Field(..., description='The name of the tag')
|
13
|
+
description: str = Field(..., description='A brief description of the tag')
|
14
|
+
|
15
|
+
|
16
|
+
class TagsMetadata(BaseModel):
|
17
|
+
tags: List[Tag] = Field(..., description='List of API tags')
|
18
|
+
|
19
|
+
|
20
|
+
TAGS_METADATA = TagsMetadata(
|
21
|
+
tags=[
|
22
|
+
Tag(name='HTTP Methods', description='Testing different HTTP verbs'),
|
23
|
+
Tag(name='Auth', description='Auth methods'),
|
24
|
+
Tag(name='Status codes', description='Generates responses with given status code'),
|
25
|
+
Tag(name='Request inspection', description='Inspect the request data'),
|
26
|
+
Tag(name='Response inspection', description='Inspect the response data like caching and headers'),
|
27
|
+
Tag(name='Response formats', description='Returns responses in different data formats'),
|
28
|
+
Tag(name='Dynamic data', description='Generates random and dynamic data'),
|
29
|
+
Tag(name='Cookies', description='Creates, reads and deletes Cookies'),
|
30
|
+
Tag(name='Images', description='Returns different image formats'),
|
31
|
+
Tag(name='Redirects', description='Returns different redirect responses'),
|
32
|
+
Tag(name='Anything', description='Returns anything that is passed to request'),
|
33
|
+
]
|
34
|
+
)
|
35
|
+
|
36
|
+
|
37
|
+
@lru_cache
|
38
|
+
def get_tags_metadata() -> List[dict]:
|
39
|
+
"""
|
40
|
+
Returns the tags metadata in the format expected by FastAPI.
|
41
|
+
"""
|
42
|
+
return [tag.model_dump() for tag in TAGS_METADATA.tags]
|
httpbinx/routers/anything.py
CHANGED
@@ -1,13 +1,25 @@
|
|
1
|
-
|
2
|
-
from
|
1
|
+
from enum import Enum
|
2
|
+
from os import path
|
3
|
+
|
4
|
+
from fastapi import APIRouter, Path
|
3
5
|
from starlette.requests import Request
|
6
|
+
from starlette.responses import FileResponse
|
4
7
|
|
5
|
-
from httpbinx.helpers import to_request_info
|
8
|
+
from httpbinx.helpers import get_bomb_file_path, to_request_info
|
6
9
|
from httpbinx.schemas import RequestInfo
|
7
10
|
|
8
11
|
router = APIRouter(tags=['Anything'])
|
9
12
|
|
10
13
|
|
14
|
+
class BombTypes(str, Enum):
|
15
|
+
"""The allowed bomb file compression types are: brotli and gzip."""
|
16
|
+
brotli = 'brotli'
|
17
|
+
gzip = 'gzip'
|
18
|
+
|
19
|
+
|
20
|
+
bombs_path: Path = get_bomb_file_path()
|
21
|
+
|
22
|
+
|
11
23
|
@router.api_route(
|
12
24
|
'/anything', # TODO path regex
|
13
25
|
response_model=RequestInfo,
|
@@ -17,3 +29,34 @@ router = APIRouter(tags=['Anything'])
|
|
17
29
|
)
|
18
30
|
async def anything(request: Request):
|
19
31
|
return await to_request_info(request)
|
32
|
+
|
33
|
+
|
34
|
+
@router.get(
|
35
|
+
'/bombs/{file}',
|
36
|
+
response_class=FileResponse,
|
37
|
+
summary='Returns a bomb file.',
|
38
|
+
description='**It may cause your client to crash! '
|
39
|
+
'References [I use Zip Bombs to Protect my Server](https://idiallo.com/blog/zipbomb-protection)**',
|
40
|
+
response_description='Return a bomb for compressed files.'
|
41
|
+
)
|
42
|
+
async def bomb_file(
|
43
|
+
*,
|
44
|
+
file: BombTypes = Path(
|
45
|
+
...,
|
46
|
+
title='Compression types',
|
47
|
+
description='The allowed bomb file compression types',
|
48
|
+
)
|
49
|
+
):
|
50
|
+
if file == BombTypes.gzip:
|
51
|
+
# dd if=/dev/zero bs=1M count=1000 | gzip -c > bomb-1GB.gz
|
52
|
+
return FileResponse(
|
53
|
+
path=path.join(bombs_path, 'bomb-1GB.gz'),
|
54
|
+
headers={'Content-Encoding': 'gzip'},
|
55
|
+
)
|
56
|
+
elif file == BombTypes.brotli:
|
57
|
+
# dd if=/dev/zero bs=1M count=1000 | brotli > bomb-1GB.br
|
58
|
+
return FileResponse(
|
59
|
+
path=path.join(bombs_path, 'bomb-1GB.br'),
|
60
|
+
headers={'Content-Encoding': 'br'},
|
61
|
+
)
|
62
|
+
raise ValueError(f'{file} is not a valid file type.')
|
httpbinx/routers/images.py
CHANGED
@@ -1,21 +1,20 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
1
|
"""Images"""
|
3
|
-
from
|
2
|
+
from pathlib import Path
|
4
3
|
|
5
4
|
from fastapi import APIRouter
|
6
5
|
from starlette.requests import Request
|
7
6
|
from starlette.responses import FileResponse
|
8
7
|
from starlette.status import HTTP_406_NOT_ACCEPTABLE
|
9
8
|
|
10
|
-
from httpbinx.helpers import status_code_response
|
9
|
+
from httpbinx.helpers import get_images_path, status_code_response
|
11
10
|
|
12
11
|
|
13
12
|
class ImageResponse(FileResponse):
|
14
13
|
"""set response headers Content-Type: image/* """
|
15
|
-
media_type = 'image/*'
|
14
|
+
media_type = 'image/*' # default
|
16
15
|
|
17
16
|
|
18
|
-
images_path =
|
17
|
+
images_path: Path = get_images_path()
|
19
18
|
|
20
19
|
router = APIRouter(
|
21
20
|
tags=['Images'],
|
@@ -32,9 +31,6 @@ router = APIRouter(
|
|
32
31
|
)
|
33
32
|
async def image(request: Request):
|
34
33
|
accept = request.headers.get('accept')
|
35
|
-
if not accept:
|
36
|
-
# Default media type to png
|
37
|
-
return await image_png()
|
38
34
|
accept = accept.lower()
|
39
35
|
if 'image/webp' in accept:
|
40
36
|
return await image_webp()
|
@@ -42,7 +38,8 @@ async def image(request: Request):
|
|
42
38
|
return await image_svg()
|
43
39
|
elif 'image/jpeg' in accept:
|
44
40
|
return await image_jpeg()
|
45
|
-
elif
|
41
|
+
elif any(x in accept for x in ['image/png', 'image/*', '*/*']):
|
42
|
+
# Default media type to png
|
46
43
|
return await image_png()
|
47
44
|
else:
|
48
45
|
return status_code_response(HTTP_406_NOT_ACCEPTABLE)
|
@@ -55,7 +52,7 @@ async def image(request: Request):
|
|
55
52
|
response_description='A PNG image.'
|
56
53
|
)
|
57
54
|
async def image_png():
|
58
|
-
return ImageResponse(path=
|
55
|
+
return ImageResponse(path=images_path / 'pig_icon.png')
|
59
56
|
|
60
57
|
|
61
58
|
@router.get(
|
@@ -65,7 +62,7 @@ async def image_png():
|
|
65
62
|
response_description='A JPEG image.'
|
66
63
|
)
|
67
64
|
async def image_jpeg():
|
68
|
-
return ImageResponse(path=
|
65
|
+
return ImageResponse(path=images_path / 'jackal.jpg')
|
69
66
|
|
70
67
|
|
71
68
|
@router.get(
|
@@ -75,7 +72,7 @@ async def image_jpeg():
|
|
75
72
|
response_description='A WEBP image.'
|
76
73
|
)
|
77
74
|
async def image_webp():
|
78
|
-
return ImageResponse(path=
|
75
|
+
return ImageResponse(path=images_path / 'wolf_1.webp')
|
79
76
|
|
80
77
|
|
81
78
|
@router.get(
|
@@ -85,4 +82,4 @@ async def image_webp():
|
|
85
82
|
response_description='An SVG image.'
|
86
83
|
)
|
87
84
|
async def image_svg():
|
88
|
-
return ImageResponse(path=
|
85
|
+
return ImageResponse(path=images_path / 'svg_logo.svg')
|
Binary file
|
Binary file
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: httpbinx
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.8.1
|
4
4
|
Summary: HTTP Request & Response Service, written in Python + FastAPI.
|
5
5
|
Author-Email: Leo <imleowoo@outlook.com>
|
6
6
|
Maintainer-Email: Leo <imleowoo@outlook.com>
|
@@ -54,13 +54,17 @@ Description-Content-Type: text/markdown
|
|
54
54
|
](https://raw.githubusercontent.com/imleowoo/httpbinx/main/httpbinx/static/images/httpbinx_cover.png)
|
55
55
|
|
56
56
|
[](https://github.com/postmanlabs/httpbin)
|
57
|
-

|
58
58
|
|
59
59
|
# httpbinx
|
60
60
|
|
61
61
|
HTTP Request & Response Service, written in Python + FastAPI.
|
62
62
|
|
63
|
-
##
|
63
|
+
## Deployed at:
|
64
|
+
|
65
|
+
- **https://httpbinx.wooe.cc**
|
66
|
+
|
67
|
+
## Reference Project
|
64
68
|
|
65
69
|
A [Kenneth Reitz](http://kennethreitz.org/bitcoin) Project. See https://github.com/postmanlabs/httpbin
|
66
70
|
|
@@ -1,21 +1,21 @@
|
|
1
|
-
httpbinx-1.
|
2
|
-
httpbinx-1.
|
3
|
-
httpbinx-1.
|
4
|
-
httpbinx-1.
|
5
|
-
httpbinx/__init__.py,sha256
|
1
|
+
httpbinx-1.8.1.dist-info/METADATA,sha256=TvHx9IGXNe2qWaF38e8o01JcIRA8SU53QoZgKif3AWY,3780
|
2
|
+
httpbinx-1.8.1.dist-info/WHEEL,sha256=tSfRZzRHthuv7vxpI4aehrdN9scLjk-dCJkPLzkHxGg,90
|
3
|
+
httpbinx-1.8.1.dist-info/entry_points.txt,sha256=sRkqxXJlZzL_lyEEQOecT_wue4JP64lYhpLwrPCZ-lI,66
|
4
|
+
httpbinx-1.8.1.dist-info/licenses/LICENSE,sha256=t6oZPzEcm1CsBu9sB_8JYTc5rSOUhyQUee5qvAg4o-A,1060
|
5
|
+
httpbinx/__init__.py,sha256=-kQbFZawSi7IDtWAo8shTSvO6CfZEbueUnFv5G7NenU,72
|
6
6
|
httpbinx/cli.py,sha256=bMPWV5HbOzqNJr3HBqFsZkaFqLI5YJneQQpAzF66mOg,1417
|
7
|
-
httpbinx/constants.py,sha256=
|
7
|
+
httpbinx/constants.py,sha256=kXeT_Yzl_-4SJT_a7RxU5dfXBTe4-b1Zg8TBF-8AGbs,870
|
8
8
|
httpbinx/examples/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
9
|
-
httpbinx/helpers.py,sha256
|
10
|
-
httpbinx/main.py,sha256=
|
11
|
-
httpbinx/meta.py,sha256=
|
9
|
+
httpbinx/helpers.py,sha256=VVwjLpEKxi_awEPqbgb8tfWnhJEHSQFTsthE0pBKgp4,4373
|
10
|
+
httpbinx/main.py,sha256=SjOjlYpaXMeSf2nqYJ-fY5RNpOFG1xEHe6bS3HM9ygg,837
|
11
|
+
httpbinx/meta.py,sha256=h6scAO050bHFiy7UG2Q8MsyJsAHWMsZAFmZntdUwTAs,1699
|
12
12
|
httpbinx/routers/__init__.py,sha256=xwbZGA3-sV07HCPAly8o5uUJGbdKH3pBHUakXEjvRK4,1409
|
13
|
-
httpbinx/routers/anything.py,sha256=
|
13
|
+
httpbinx/routers/anything.py,sha256=_FK1D9xEONlVIF_rvlqe_tBSsmG7ba8K_m-kGFotWWg,1923
|
14
14
|
httpbinx/routers/auth.py,sha256=nGZA1aQtrS2B74vM2NORHSWMXf5q25JC2J63hAO2_Us,717
|
15
15
|
httpbinx/routers/cookies.py,sha256=TB3ADXXg0kgZX5nE1QlrVk1mKXjdFAMJ7iMfd8kfMBc,2341
|
16
16
|
httpbinx/routers/dynamicdata.py,sha256=Cas2JWkQnCaKNuE0Vw84h4YKcfl8PlsvAy6kYdvw_f4,6790
|
17
17
|
httpbinx/routers/httpmethods.py,sha256=X9YPADi9D6FQnybJWyXc5BTDErgFZ5Xa4OIy7OKAifQ,1531
|
18
|
-
httpbinx/routers/images.py,sha256=
|
18
|
+
httpbinx/routers/images.py,sha256=d38pKQMinCbnipaBmE0gBlYar8Kog0ZOQEaaLregLZ8,2185
|
19
19
|
httpbinx/routers/inspection/__init__.py,sha256=OMPci9p6uK9L6uFKQKbIqOn-r5MndCWSqlw-bJsUE3E,166
|
20
20
|
httpbinx/routers/inspection/request.py,sha256=8b5HEuX2ED-YjMB5S0h-2xZDAmyo4ru9RX2S1tCwaqs,1224
|
21
21
|
httpbinx/routers/inspection/response.py,sha256=yJ46k1O80WO8hq4gF09KHrsQJeP7Cn0aj6AAphfyyAY,2863
|
@@ -24,6 +24,8 @@ httpbinx/routers/responseformats.py,sha256=sqRLzSFjUmN5B9urbMVR7X_AydqvuT1pvHGIX
|
|
24
24
|
httpbinx/routers/statuscodes.py,sha256=Iu0dcGsXLv34otIrH6WrWm_vOHt-9zAnblojM-d_qV0,1740
|
25
25
|
httpbinx/schemas.py,sha256=QxBcsd4Go1azLPWF8E_uLyUVcnzI7Rwny-woDPvAzp0,4029
|
26
26
|
httpbinx/static/UTF-8-demo.txt,sha256=rtAgU6uoYvQ0w7ij9JbkKdw6c3q-RchO1bAmrVzhksw,14058
|
27
|
+
httpbinx/static/bombs/bomb-1GB.br,sha256=pRVe549TQ4bzSP231INlng3sL_cGaDY6FQdaF7XtYKY,828
|
28
|
+
httpbinx/static/bombs/bomb-1GB.gz,sha256=9k1T0WSAGsXMi3e7kH-v_U8bZHMF3sgb4jOYroJ4ymY,1019197
|
27
29
|
httpbinx/static/favicon.png,sha256=EsETjrMhmZy6X3LgRmOr_nu6dMWYGPGQ4XH3ESebrco,1291
|
28
30
|
httpbinx/static/images/httbinx_logo.png,sha256=wqrQoDwsMvFgXtXeHfmtTqFrnsTA94N_esLo-5yfF58,3893
|
29
31
|
httpbinx/static/images/httpbinx_cover.png,sha256=S8UtWBtwrfOUJTxyB1KsF9BFIh2UaRI3MEaZYemgLdU,2257
|
@@ -34,5 +36,4 @@ httpbinx/static/images/wolf_1.webp,sha256=Vnz6-U668nnOpOsLwFxGVQIftO4ASspSwJZwnT
|
|
34
36
|
httpbinx/templates/moby.html,sha256=o519fgNb4vga6kx6ARW3MYpV7xrRJFzmyrOZwUmrYw8,3962
|
35
37
|
httpbinx/templates/sample.xml,sha256=K12JbH36KNaAaBLkfyOhsUeXc-GfLHluHffGY3l2-V0,550
|
36
38
|
httpbinx/templates/trackingscripts.html,sha256=3E-Lg6NpBpF74H3srJuswtHfD87gNEsuVxsjm9cqIYM,625
|
37
|
-
httpbinx/
|
38
|
-
httpbinx-1.7.0.dist-info/RECORD,,
|
39
|
+
httpbinx-1.8.1.dist-info/RECORD,,
|
httpbinx/utils.py
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
|
-
from functools import lru_cache
|
3
|
-
from os import path
|
4
|
-
|
5
|
-
|
6
|
-
@lru_cache(maxsize=128)
|
7
|
-
def get_templates_abspath(subdir: str = None) -> str:
|
8
|
-
"""Return templates' folder abspath
|
9
|
-
TODO use Jinja2Templates
|
10
|
-
"""
|
11
|
-
# os.path.join(os.getcwd(), 'httpbin', 'templates')
|
12
|
-
templates_abspath = path.join(path.dirname(__file__), 'templates')
|
13
|
-
if subdir is None:
|
14
|
-
return templates_abspath
|
15
|
-
return path.join(templates_abspath, subdir)
|
File without changes
|
File without changes
|