Add functionality to generate valid `multipart/form-data`
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 157
- Forks
- 36
- PR merge metrics
- No merged PRs in 30d
Description
Provide a MultipartBuilder that can be used to produce valid multipart/form-data and offers an API that avoids user errors as much as possible. This can be used in tests or HTTP clients. Having both parsers and generators in one library seems to be a good fit.
API Idea
R = TypeVar("R")
_identity = lambda x: x
class MultipartBuilder(Generic[R]):
def __init__(self, boundary: str, write_func: Callable[[Union[bytes,bytearray]], R] = _identity):
" Create a new builder. "
def add_part(self, name: str, filename: Optional[str] = None, content_type: Optional[str] = None) -> R:
"Start a new text field or file upload."
def write(self, chunk: Union[str, bytes, bytearray]) -> R:
"Write a chunk of data to the current field."
def close(self) -> R:
"Write the final delimiter"
The write_func is responsible for writing a single bytearray to the target stream, or return a value that represents the intent to do so. The builder functions return whatever the write function returns. This allows this builder to be used in both blocking and non-blocking environments. If you pass in an async function, then the return value R will be a coroutine you can await.
# Blocking
def blocking(target: io.BufferedWriter):
with MultipartBuilder("--foo", target.write) as builder:
builder.add_part("name", "filename.txt")
builder.write("content")
# Async
async def non_blocking(target: asyncio.StreamWriter):
async with MultipartBuilder("--foo", target.write) as builder:
await builder.add_part("name", "filename.txt")
await builder.write("content")
# SansIO
def sans_io() -> Iterator[bytes]:
builder = MultipartBuilder("--foo", lambda x: x)
yield builder.add_part("name", "filename.txt")
yield builder.write("content")
yield builder.close()
Not sure if this is a good idea, though. It might be a little bit to clever and having dedicated APIs for AsyncMultipartBuilder and SansIOMultipartBuilder with proper method signatures may be more intuitive.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reviewing the existing Python multipart parser API and project structure to determine where a generator belongs. Compare the proposed MultipartBuilder with dedicated asynchronous and Sans I/O alternatives before choosing an API. Done means the agreed builder can produce valid multipart/form-data for text fields and file uploads in the supported execution styles.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- api, backend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 32/100