Skip to content

Commit

Permalink
🔖 Release 2.4.3 (#52)
Browse files Browse the repository at this point in the history
Function parse_it is improved.

- Added support for niquests.Response
- Added support for kiss_headers.Headers (deepcopy returned)
  • Loading branch information
Ousret authored Nov 12, 2023
1 parent fe18870 commit 598676b
Show file tree
Hide file tree
Showing 9 changed files with 142 additions and 42 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: [3.9]
python-version: ["3.10"]
os: [ubuntu-latest]

steps:
Expand All @@ -38,4 +38,4 @@ jobs:
isort --check kiss_headers
- name: Code format (Black)
run: |
black --check --diff --target-version=py37 kiss_headers
black --check --diff kiss_headers
86 changes: 86 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
name: Publish to PyPI

on:
release:
types:
- created

permissions:
contents: read

jobs:
build:
name: "Build dists"
runs-on: "ubuntu-latest"
outputs:
hashes: ${{ steps.hash.outputs.hashes }}

steps:
- name: "Checkout repository"
uses: "actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608"

- name: "Setup Python"
uses: "actions/setup-python@61a6322f88396a6271a6ee3565807d608ecaddd1"
with:
python-version: "3.x"

- name: "Install dependencies"
run: python -m pip install build

- name: "Build dists"
run: |
SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct) \
python -m build
- name: "Generate hashes"
id: hash
run: |
cd dist && echo "::set-output name=hashes::$(sha256sum * | base64 -w0)"
- name: "Upload dists"
uses: "actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce"
with:
name: "dist"
path: "dist/"
if-no-files-found: error
retention-days: 5

provenance:
needs: [build]
permissions:
actions: read
contents: write
id-token: write # Needed to access the workflow's OIDC identity.
uses: "slsa-framework/slsa-github-generator/.github/workflows/[email protected]"
with:
base64-subjects: "${{ needs.build.outputs.hashes }}"
upload-assets: true
compile-generator: true # Workaround for https://github.com/slsa-framework/slsa-github-generator/issues/1163

publish:
name: "Publish"
if: startsWith(github.ref, 'refs/tags/')
environment:
name: pypi
url: https://pypi.org/p/kiss-headers
needs: ["build", "provenance"]
permissions:
contents: write
id-token: write # Needed for trusted publishing to PyPI.
runs-on: "ubuntu-latest"

steps:
- name: "Download dists"
uses: "actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a"
with:
name: "dist"
path: "dist/"

- name: "Upload dists to GitHub Release"
env:
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
run: |
gh release upload ${{ github.ref_name }} dist/* --repo ${{ github.repository }}
- name: "Publish dists to PyPI"
uses: "pypa/gh-action-pypi-publish@f8c70e705ffc13c3b4d1221169b84f12a75d6ca8" # v1.8.8
31 changes: 0 additions & 31 deletions .github/workflows/pythonpublish.yml

This file was deleted.

2 changes: 1 addition & 1 deletion .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: [3.7, 3.8, 3.9, "3.10", "3.11", "3.12-dev"]
python-version: [3.7, 3.8, 3.9, "3.10", "3.11", "3.12"]
os: [ubuntu-latest]

steps:
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ Plus all the features that you would expect from handling headers...

* Properties syntax for headers and attribute in a header.
* Supports headers and attributes OneToOne, OneToMany and ManySquashedIntoOne.
* Capable of parsing `bytes`, `fp`, `str`, `dict`, `email.Message`, `requests.Response`, `httpx._models.Response` and `urllib3.HTTPResponse`.
* Capable of parsing `bytes`, `fp`, `str`, `dict`, `email.Message`, `requests.Response`, `niquests.Response`, `httpx._models.Response` and `urllib3.HTTPResponse`.
* Automatically unquote and unfold the value of an attribute when retrieving it.
* Keep headers and attributes ordering.
* Case-insensitive with header name and attribute key.
Expand All @@ -73,6 +73,8 @@ Whatever you like, use `pipenv` or `pip`, it simply works. Requires Python 3.7+
pip install kiss-headers --upgrade
```

This project is included in [Niquests](https://github.com/jawah/niquests)! Your awesome drop-in replacement for Requests!

### 🍰 Usage

#### Quick start
Expand Down
10 changes: 7 additions & 3 deletions kiss_headers/api.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from copy import deepcopy
from email.message import Message
from email.parser import HeaderParser
from io import BufferedReader, RawIOBase
Expand Down Expand Up @@ -27,17 +28,20 @@
def parse_it(raw_headers: Any) -> Headers:
"""
Just decode anything that could contain headers. That simple PERIOD.
:param raw_headers: Accept bytes, str, fp, dict, JSON, email.Message, requests.Response, urllib3.HTTPResponse and httpx.Response.
If passed with a Headers instance, return a deep copy of it.
:param raw_headers: Accept bytes, str, fp, dict, JSON, email.Message, requests.Response, niquests.Response, urllib3.HTTPResponse and httpx.Response.
:raises:
TypeError: If passed argument cannot be parsed to extract headers from it.
"""

if isinstance(raw_headers, Headers):
return deepcopy(raw_headers)

headers: Optional[Iterable[Tuple[Union[str, bytes], Union[str, bytes]]]] = None

if isinstance(raw_headers, str):
if raw_headers.startswith("{") and raw_headers.endswith("}"):
return decode(json_loads(raw_headers))

headers = HeaderParser().parsestr(raw_headers, headersonly=True).items()
elif (
isinstance(raw_headers, bytes)
Expand All @@ -54,7 +58,7 @@ def parse_it(raw_headers: Any) -> Headers:
r = extract_class_name(type(raw_headers))

if r:
if r == "requests.models.Response":
if r in ["requests.models.Response", "niquests.models.Response"]:
headers = []
for header_name in raw_headers.raw.headers:
for header_content in raw_headers.raw.headers.getlist(header_name):
Expand Down
6 changes: 3 additions & 3 deletions kiss_headers/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
OUTPUT_LOCK_TYPE: bool = False


class Header(object):
class Header:
"""
Object representation of a single Header.
"""
Expand Down Expand Up @@ -606,7 +606,7 @@ def __contains__(self, item: str) -> bool:
return False


class Headers(object):
class Headers:
"""
Object-oriented representation for Headers. Contains a list of Header with some level of abstraction.
Combine advantages of dict, CaseInsensibleDict, list, multi-dict, and native objects.
Expand Down Expand Up @@ -1211,7 +1211,7 @@ def __dir__(self) -> Iterable[str]:
)


class Attributes(object):
class Attributes:
"""
Dedicated class to handle attributes within a Header. Wrap an AttributeBag and offer methods to manipulate it
with ease.
Expand Down
2 changes: 1 addition & 1 deletion kiss_headers/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
Expose version
"""

__version__ = "2.4.2"
__version__ = "2.4.3"
VERSION = __version__.split(".")
39 changes: 39 additions & 0 deletions tests/test_headers_from_string.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,39 @@
"\n", "\r\n"
)

RAW_HEADERS_WITH_CONNECT = """HTTP/1.1 200 Connection established
HTTP/2 200
date: Tue, 28 Sep 2021 13:45:34 GMT
content-type: application/epub+zip
content-length: 3706401
content-disposition: filename=ipython-readthedocs-io-en-stable.epub
x-amz-id-2: 2PO2WHP4qGqkhyC1VbRE2KLN2g4uk38vYzaNJDU/OBSxh4lUtYgERD2FNAOPkKPD1a6rsNBMeKI=
x-amz-request-id: 21E21R71FAY4WQKT
last-modified: Sat, 25 Sep 2021 00:43:37 GMT
etag: "6f512f04591f7667486d044c54708448"
x-served: Nginx-Proxito-Sendfile
x-backend: web-i-078619706c1392c2c
x-rtd-project: ipython
x-rtd-version: stable
x-rtd-path: /proxito/epub/ipython/stable/ipython.epub
x-rtd-domain: ipython.readthedocs.io
x-rtd-version-method: path
x-rtd-project-method: subdomain
referrer-policy: no-referrer-when-downgrade
permissions-policy: interest-cohort=()
strict-transport-security: max-age=31536000; includeSubDomains; preload
cf-cache-status: HIT
age: 270
expires: Tue, 28 Sep 2021 15:45:34 GMT
cache-control: public, max-age=7200
accept-ranges: bytes
expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
server: cloudflare
cf-ray: 695d69b549330686-LHR""".replace(
"\n", "\r\n"
)


class MyKissHeadersFromStringTest(unittest.TestCase):
headers: Headers
Expand Down Expand Up @@ -169,6 +202,12 @@ def test_fixed_type_output(self):

self.assertEqual(str, type(headers.accept[-1].q))

def test_parse_with_extra_connect(self):
headers: Headers = parse_it(RAW_HEADERS_WITH_CONNECT)

self.assertTrue("Date" in headers)
self.assertTrue("Server" in headers)


if __name__ == "__main__":
unittest.main()

0 comments on commit 598676b

Please sign in to comment.