{"id":23131603,"url":"https://github.com/peopledoc/multipart-reader","last_synced_at":"2025-08-17T08:31:32.577Z","repository":{"id":57443987,"uuid":"48739012","full_name":"peopledoc/multipart-reader","owner":"peopledoc","description":"Multipart/* reader extracted from awsome `aiohttp` project, cf.: http://aiohttp.readthedocs.org/en/stable/multipart.html.","archived":false,"fork":false,"pushed_at":"2023-02-12T10:48:51.000Z","size":32,"stargazers_count":5,"open_issues_count":2,"forks_count":3,"subscribers_count":13,"default_branch":"master","last_synced_at":"2025-06-26T15:52:17.120Z","etag":null,"topics":["approved-public","ghec-mig-migrated"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/peopledoc.png","metadata":{"files":{"readme":"README.rst","changelog":"CHANGELOG","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2015-12-29T09:14:47.000Z","updated_at":"2023-09-27T19:09:58.000Z","dependencies_parsed_at":"2023-07-15T12:49:17.135Z","dependency_job_id":null,"html_url":"https://github.com/peopledoc/multipart-reader","commit_stats":null,"previous_names":["novafloss/multipart-reader"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/peopledoc/multipart-reader","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peopledoc%2Fmultipart-reader","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peopledoc%2Fmultipart-reader/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peopledoc%2Fmultipart-reader/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peopledoc%2Fmultipart-reader/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/peopledoc","download_url":"https://codeload.github.com/peopledoc/multipart-reader/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peopledoc%2Fmultipart-reader/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270822958,"owners_count":24652022,"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","status":"online","status_checked_at":"2025-08-17T02:00:09.016Z","response_time":129,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["approved-public","ghec-mig-migrated"],"created_at":"2024-12-17T11:15:29.408Z","updated_at":"2025-08-17T08:31:32.279Z","avatar_url":"https://github.com/peopledoc.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"================\nMultipart Reader\n================\n\n.. image:: https://travis-ci.org/novafloss/multipart-reader.svg\n   :target: https://travis-ci.org/novafloss/multipart-reader\n   :alt: We are under CI!!\n\n\nPermits to read a multipart content like, mixed, related, etc.\n\nThanks to the *aiohttp* project for the implementation, cf.:\nhttp://aiohttp.readthedocs.org/en/stable/multipart.html. Unfortunately lot of\npeople have not yet moved to asyncio, or do not want the full *aiohttp* stack\nto read the multipart content. \n\nHere we tried to keep all the *aiohttp* logic and coverage but the coroutines\nmechanism.\n\n\nWhat it does\n============\n\nIt reads the same way multpart/x contents. Lets say we have the following\n*multipart/related* content::\n\n    \u003e\u003e\u003e import json\n\n    \u003e\u003e\u003e from email.mime.multipart import MIMEMultipart\n    \u003e\u003e\u003e from email.mime.base import MIMEBase\n\n    \u003e\u003e\u003e multipart = MIMEMultipart('related')\n\n    \u003e\u003e\u003e part = MIMEBase('application', 'json')\n    \u003e\u003e\u003e part.set_payload(json.dumps({'foo': 'bar'}))\n    \u003e\u003e\u003e multipart.attach(part)\n\n    \u003e\u003e\u003e part = MIMEBase('application', 'octet-stream')\n    \u003e\u003e\u003e part.set_payload(b\"Python will save the world. I don't know how. But it will.\")\n    \u003e\u003e\u003e part.add_header('Content-Disposition', 'attachment', filename='python-save-the-world.txt')\n    \u003e\u003e\u003e multipart.attach(part)\n\nHere is how we can read it::\n\n    \u003e\u003e\u003e import io\n\n    \u003e\u003e\u003e from multipart_reader import MultipartReader\n\n    \u003e\u003e\u003e content = multipart.as_string().split('\\n\\n', 1)[1]\n    \u003e\u003e\u003e headers = dict(multipart.items())\n\n    \u003e\u003e\u003e stream = io.BytesIO()\n    \u003e\u003e\u003e stream.write(content)\n    \u003e\u003e\u003e stream.seek(0)\n\n    \u003e\u003e\u003e reader = MultipartReader(headers, stream)\n\n    \u003e\u003e\u003e json_part = reader.next()\n    \u003e\u003e\u003e json_part.json()\n    {'foo': 'bar'}\n\n    \u003e\u003e\u003e file_part = reader.next()\n    \u003e\u003e\u003e file_part.read()\n    \"Python will save the world. I don't know how. But it will.\"\n\n    \u003e\u003e\u003e file_part.filename\n    'python-save-the-world.txt'\n\nThat's it ...\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpeopledoc%2Fmultipart-reader","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpeopledoc%2Fmultipart-reader","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpeopledoc%2Fmultipart-reader/lists"}