{"id":14065392,"url":"https://github.com/mnot/http_sfv","last_synced_at":"2025-06-16T23:05:55.263Z","repository":{"id":57466775,"uuid":"158344045","full_name":"mnot/http_sfv","owner":"mnot","description":"Parse and serialise HTTP structured field values","archived":false,"fork":false,"pushed_at":"2024-01-25T05:12:05.000Z","size":235,"stargazers_count":13,"open_issues_count":1,"forks_count":0,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-06-03T20:09:23.957Z","etag":null,"topics":["headers","http","parser","python"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mnot.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-11-20T06:51:46.000Z","updated_at":"2024-01-13T23:59:10.000Z","dependencies_parsed_at":"2024-01-24T01:37:44.157Z","dependency_job_id":"193fef6c-73b6-46dd-97b1-8e5fc2be3503","html_url":"https://github.com/mnot/http_sfv","commit_stats":{"total_commits":242,"total_committers":2,"mean_commits":121.0,"dds":0.004132231404958664,"last_synced_commit":"72c9899348a80f960c784c8b7ee6c1ed8b6fc244"},"previous_names":["mnot/shhh"],"tags_count":19,"template":false,"template_full_name":null,"purl":"pkg:github/mnot/http_sfv","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mnot%2Fhttp_sfv","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mnot%2Fhttp_sfv/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mnot%2Fhttp_sfv/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mnot%2Fhttp_sfv/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mnot","download_url":"https://codeload.github.com/mnot/http_sfv/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mnot%2Fhttp_sfv/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":260256258,"owners_count":22981807,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["headers","http","parser","python"],"created_at":"2024-08-13T07:04:28.145Z","updated_at":"2025-06-16T23:05:55.241Z","avatar_url":"https://github.com/mnot.png","language":"Python","readme":"\n# HTTP Structured Field Values in Python\n\n[![Actions Status](https://github.com/mnot/http_sfv/workflows/CI/badge.svg)](https://github.com/mnot/http_sfv/actions)\n\n\n# This Package is DEPRECATED\n\nSee the [http-sf package](https://pypi.org/project/http-sf/) for a replacement. This package will only be updated for security issues, and may be yanked in the future.\n\n# Introduction\n\nThis is a [Python 3](https://python.org/) library implementing parsing and serialisation of [HTTP Structured Fields](https://httpwg.org/http-extensions/draft-ietf-httpbis-header-structure.html).\n\nThe library's initial purpose is to prove the algorithms in the specification; as a result, it is not at all optimised. It tracks the specification closely, but since it is not yet an RFC, may change at any time.\n\n_Currently, this implements [draft-ietf-httpbis-sfbis-03](https://datatracker.ietf.org/doc/draft-ietf-httpbis-sfbis/)._\n\n## Python API\n\nThere are three top-level types for Structured Field Values; `Dictionary`, `List` and `Item`. After instantiation, each can be used to parse a string HTTP header field value by calling `.parse()`:\n\n~~~ python\n\u003e\u003e\u003e from http_sfv import List\n\u003e\u003e\u003e my_list = List()\n\u003e\u003e\u003e my_list.parse(b\"foo; a=1, bar; b=2\")\n~~~\n\nNote that `.parse()` takes a bytes-like object. If you want to parse a string, please `.encode()` it first.\n\nMembers of Lists and Dictionaries are available by normal Pythonic list and dictionary methods, respectively:\n\n~~~ python\n\u003e\u003e\u003e my_list\n[\u003chttp_sfv.item.Item object at 0x106d25190\u003e, \u003chttp_sfv.item.Item object at 0x106d25210\u003e]\n\u003e\u003e\u003e my_list[0]\n\u003chttp_sfv.item.Item object at 0x106d25190\u003e\n~~~\n\nItems (whether top-level or inside a list or dictionary value) can have their values accessed with the `.value` property:\n\n~~~ python\n\u003e\u003e\u003e my_list[0].value\n'foo'\n~~~\n\nParameters on Items (and Inner Lists) can be accessed using the `.params` property, which is a dictionary:\n\n~~~ python\n\u003e\u003e\u003e my_list[0].params['a']\n1\n~~~\n\nNote that Tokens and Strings both evaluate as Python strings, but Tokens have a different class:\n\n~~~ python\n\u003e\u003e\u003e type(my_list[0].value)\n\u003cclass 'http_sfv.token.Token'\u003e\n~~~\n\nThat means that you need to create Tokens explicitly:\n\n~~~ python\n\u003e\u003e\u003e from http_sfv import Token\n\u003e\u003e\u003e my_list.append(Token('bar'))\n\u003e\u003e\u003e my_list[-1]\n'bar'\n~~~\n\nLikewise, Display Strings are represented using DisplayString objects; Dates as `datetime.datetime` objects.\n\nIf you compare two Items, they'll be considered to be equivalent if their values match, even when their parameters are different:\n\n~~~ python\n\u003e\u003e\u003e Token('foo') in my_list  # note that my_list's 'foo' has a parameter\nTrue\n\u003e\u003e\u003e my_list.count(Token(\"foo\"))\n1\n~~~\n\nInner Lists can be added by passing a list:\n\n~~~ python\n\u003e\u003e\u003e my_list.append(['another_thing', 'and_another'])\n\u003e\u003e\u003e print(my_list)\nfoo;a=1, bar;b=2, bar, (\"another_thing\" \"and_another\")\n\u003e\u003e\u003e my_list[-1][-1].params['a'] = True\n~~~\n\nDictionaries, Lists, and Items can be instantiated with a value:\n\n~~~ python\n\u003e\u003e\u003e from http_sfv import Dictionary\n\u003e\u003e\u003e my_dictionary = Dictionary({'a': '1', 'b': 2, 'c': Token('foo')})\n\u003e\u003e\u003e my_dictionary\n{'a': \u003chttp_sfv.item.Item object at 0x106a94c40\u003e, 'b': \u003chttp_sfv.item.Item object at 0x106a94d00\u003e, 'c': \u003chttp_sfv.item.Item object at 0x106a94dc0\u003e}\n~~~\n\nOnce instantiated, parameters can then be accessed:\n\n~~~ python\n\u003e\u003e\u003e my_dictionary['b'].params['1'] = 2.0\n~~~\n\nFinally, to serialise a field value, just evaluate it as a string:\n\n~~~ python\n\u003e\u003e\u003e print(my_dictionary)\na=1, b=2;b1=2.0, c=foo\n~~~\n\n\n## Command Line Use\n\nYou can validate and examine the data model of a field value by calling the library on the command line, using `-d`, `-l` and `-i` to denote dictionaries, lists or items respectively; e.g.,\n\n~~~ example\n\u003e python3 -m http_sfv -i \"foo;bar=baz\"\n[\n    {\n        \"__type\": \"token\",\n        \"value\": \"foo\"\n    },\n    {\n        \"bar\": {\n            \"__type\": \"token\",\n            \"value\": \"baz\"\n        }\n    }\n]\n~~~\n\nor:\n\n~~~ example\n\u003e python3 -m http_sfv -i \"foo;\u0026bar=baz\"\nFAIL: Key does not begin with lcalpha or * at: \u0026bar=baz\n~~~\n\nNote that if successful, the output is in the JSON format used by the [test suite](https://github.com/httpwg/structured-header-tests/).\n","funding_links":[],"categories":["Python"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmnot%2Fhttp_sfv","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmnot%2Fhttp_sfv","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmnot%2Fhttp_sfv/lists"}