rapcsv 0.0.2__cp38-cp38-manylinux_2_28_x86_64.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.
rapcsv/__init__.py ADDED
@@ -0,0 +1,16 @@
1
+ """Streaming async CSV — no fake async, no GIL stalls."""
2
+
3
+ from typing import List
4
+
5
+ try:
6
+ from _rapcsv import Reader, Writer # type: ignore[import-not-found]
7
+ except ImportError:
8
+ try:
9
+ from rapcsv._rapcsv import Reader, Writer
10
+ except ImportError:
11
+ raise ImportError(
12
+ "Could not import _rapcsv. Make sure rapcsv is built with maturin."
13
+ )
14
+
15
+ __version__: str = "0.0.2"
16
+ __all__: List[str] = ["Reader", "Writer"]
rapcsv/_rapcsv.pyi ADDED
@@ -0,0 +1,11 @@
1
+ """Type stubs for _rapcsv Rust extension module."""
2
+
3
+ from typing import Coroutine, Any, List
4
+
5
+ class Reader:
6
+ def __init__(self, path: str) -> None: ...
7
+ def read_row(self) -> Coroutine[Any, Any, List[str]]: ...
8
+
9
+ class Writer:
10
+ def __init__(self, path: str) -> None: ...
11
+ def write_row(self, row: List[str]) -> Coroutine[Any, Any, None]: ...
rapcsv/py.typed ADDED
File without changes
@@ -0,0 +1,226 @@
1
+ Metadata-Version: 2.4
2
+ Name: rapcsv
3
+ Version: 0.0.2
4
+ Classifier: Development Status :: 3 - Alpha
5
+ Classifier: Intended Audience :: Developers
6
+ Classifier: License :: OSI Approved :: MIT License
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: Programming Language :: Python :: 3.8
9
+ Classifier: Programming Language :: Python :: 3.9
10
+ Classifier: Programming Language :: Python :: 3.10
11
+ Classifier: Programming Language :: Python :: 3.11
12
+ Classifier: Programming Language :: Python :: 3.12
13
+ Summary: Streaming async CSV — no fake async, no GIL stalls.
14
+ Keywords: async,csv,streaming,async-io
15
+ Author: RAP Project
16
+ License: MIT
17
+ Requires-Python: >=3.8
18
+ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
19
+
20
+ # rapcsv
21
+
22
+ **Streaming async CSV — no fake async, no GIL stalls.**
23
+
24
+ [![PyPI version](https://img.shields.io/pypi/v/rapcsv.svg)](https://pypi.org/project/rapcsv/)
25
+ [![Downloads](https://pepy.tech/badge/rapcsv)](https://pepy.tech/project/rapcsv)
26
+ [![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/)
27
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
28
+
29
+ ## Overview
30
+
31
+ `rapcsv` provides true async CSV reading and writing for Python, backed by Rust and Tokio. Unlike libraries that wrap blocking I/O in `async` syntax, `rapcsv` guarantees that all CSV operations execute **outside the Python GIL**, ensuring event loops never stall under load, even when processing large files.
32
+
33
+ **Roadmap Goal**: Achieve drop-in replacement compatibility with `aiocsv`, enabling seamless migration with true async performance. See [ROADMAP.md](https://github.com/eddiethedean/rapcsv/blob/main/ROADMAP.md) for details.
34
+
35
+ ## Why `rap*`?
36
+
37
+ Packages prefixed with **`rap`** stand for **Real Async Python**. Unlike many libraries that merely wrap blocking I/O in `async` syntax, `rap*` packages guarantee that all I/O work is executed **outside the Python GIL** using native runtimes (primarily Rust). This means event loops are never stalled by hidden thread pools, blocking syscalls, or cooperative yielding tricks. If a `rap*` API is `async`, it is *structurally non-blocking by design*, not by convention. The `rap` prefix is a contract: measurable concurrency, real parallelism, and verifiable async behavior under load.
38
+
39
+ See the [rap-manifesto](https://github.com/eddiethedean/rap-manifesto) for philosophy and guarantees.
40
+
41
+ ## Features
42
+
43
+ - ✅ **True async** CSV reading and writing
44
+ - ✅ **Streaming support** for large files
45
+ - ✅ **Native Rust-backed** execution (Tokio)
46
+ - ✅ **Zero Python thread pools**
47
+ - ✅ **Event-loop-safe** concurrency under load
48
+ - ✅ **GIL-independent** I/O operations
49
+ - ✅ **Verified** by Fake Async Detector
50
+
51
+ ## Requirements
52
+
53
+ - Python 3.8+
54
+ - Rust 1.70+ (for building from source)
55
+
56
+ ## Installation
57
+
58
+ ```bash
59
+ pip install rapcsv
60
+ ```
61
+
62
+ ### Building from Source
63
+
64
+ ```bash
65
+ git clone https://github.com/eddiethedean/rapcsv.git
66
+ cd rapcsv
67
+ pip install maturin
68
+ maturin develop
69
+ ```
70
+
71
+ ---
72
+
73
+ ## Usage
74
+
75
+ ```python
76
+ import asyncio
77
+ from rapcsv import Reader, Writer
78
+
79
+ async def main():
80
+ # Write CSV file (one row per Writer instance for MVP)
81
+ writer = Writer("output.csv")
82
+ await writer.write_row(["name", "age", "city"])
83
+
84
+ # Read CSV file (reads first row)
85
+ reader = Reader("output.csv")
86
+ row = await reader.read_row()
87
+ print(row) # Output: ['name', 'age', 'city']
88
+
89
+ asyncio.run(main())
90
+ ```
91
+
92
+ ### Writing Multiple Rows
93
+
94
+ ```python
95
+ import asyncio
96
+ from rapcsv import Writer
97
+
98
+ async def main():
99
+ # Write multiple rows with a single Writer instance (file handle reused)
100
+ writer = Writer("output.csv")
101
+ rows = [
102
+ ["name", "age", "city"],
103
+ ["Alice", "30", "New York"],
104
+ ["Bob", "25", "London"],
105
+ ]
106
+
107
+ for row in rows:
108
+ await writer.write_row(row)
109
+
110
+ # Verify file contents
111
+ with open("output.csv") as f:
112
+ print(f.read())
113
+
114
+ asyncio.run(main())
115
+ ```
116
+
117
+ **Note**: The Writer reuses the file handle across multiple `write_row()` calls for efficient writing. The Reader maintains position state across `read_row()` calls.
118
+
119
+ ## API Reference
120
+
121
+ ### `Reader(path: str)`
122
+
123
+ Create a new async CSV reader.
124
+
125
+ **Parameters:**
126
+ - `path` (str): Path to the CSV file to read
127
+
128
+ **Example:**
129
+ ```python
130
+ reader = Reader("data.csv")
131
+ ```
132
+
133
+ ### `Reader.read_row() -> List[str]`
134
+
135
+ Read the next row from the CSV file.
136
+
137
+ **Returns:**
138
+ - `List[str]`: A list of string values for the row, or an empty list if EOF
139
+
140
+ **Raises:**
141
+ - `IOError`: If the file cannot be read or parsed
142
+
143
+ **Note**: The Reader maintains position state across `read_row()` calls, reading sequentially through the file.
144
+
145
+ ### `Writer(path: str)`
146
+
147
+ Create a new async CSV writer.
148
+
149
+ **Parameters:**
150
+ - `path` (str): Path to the CSV file to write
151
+
152
+ **Example:**
153
+ ```python
154
+ writer = Writer("output.csv")
155
+ ```
156
+
157
+ ### `Writer.write_row(row: List[str]) -> None`
158
+
159
+ Write a row to the CSV file.
160
+
161
+ **Parameters:**
162
+ - `row` (List[str]): A list of string values to write as a CSV row
163
+
164
+ **Raises:**
165
+ - `IOError`: If the file cannot be written
166
+
167
+ **Note**: The Writer reuses the file handle across multiple `write_row()` calls for efficient writing. Proper RFC 4180 compliant CSV escaping and quoting is applied automatically.
168
+
169
+ ## Benchmarks
170
+
171
+ This package passes the [Fake Async Detector](https://github.com/eddiethedean/rap-bench). Benchmarks are available in the [rap-bench](https://github.com/eddiethedean/rap-bench) repository.
172
+
173
+ Run the detector yourself:
174
+
175
+ ```bash
176
+ pip install rap-bench
177
+ rap-bench detect rapcsv
178
+ ```
179
+
180
+ ## Roadmap
181
+
182
+ See [ROADMAP.md](https://github.com/eddiethedean/rapcsv/blob/main/ROADMAP.md) for detailed development plans. Key goals include:
183
+ - Drop-in replacement for `aiocsv` (Phase 1)
184
+ - Full streaming support for large files
185
+ - Comprehensive CSV dialect support
186
+ - Zero-copy optimizations
187
+
188
+ ## Related Projects
189
+
190
+ - [rap-manifesto](https://github.com/eddiethedean/rap-manifesto) - Philosophy and guarantees
191
+ - [rap-bench](https://github.com/eddiethedean/rap-bench) - Fake Async Detector CLI
192
+ - [rapfiles](https://github.com/eddiethedean/rapfiles) - True async filesystem I/O
193
+ - [rapsqlite](https://github.com/eddiethedean/rapsqlite) - True async SQLite
194
+
195
+ ## Limitations (v0.0.2)
196
+
197
+ **Current limitations:**
198
+ - Reader still reads entire file into memory on each call (streaming improvements planned)
199
+ - No advanced CSV dialect support (delimiters, quote characters, line terminators)
200
+ - No header detection or manipulation
201
+ - Not yet a drop-in replacement for `aiocsv` (goal for Phase 1)
202
+ - Not designed for synchronous use cases
203
+
204
+ **Recent improvements (v0.0.2):**
205
+ - ✅ Security fixes: Upgraded dependencies (pyo3 0.27, pyo3-async-runtimes 0.27), fixed CSV injection vulnerability
206
+ - ✅ Position tracking: Reader now maintains position state across `read_row()` calls
207
+ - ✅ File handle reuse: Writer reuses file handle across multiple `write_row()` calls
208
+ - ✅ CSV escaping: Implemented RFC 4180 compliant CSV escaping and quoting
209
+ - ✅ Input validation: Added path validation (non-empty, no null bytes)
210
+ - ✅ Improved error handling: Enhanced error messages with file path context
211
+ - ✅ Type stubs: Added `.pyi` type stubs for better IDE support and type checking
212
+
213
+ **Roadmap**: See [ROADMAP.md](https://github.com/eddiethedean/rapcsv/blob/main/ROADMAP.md) for planned improvements. Our goal is to achieve drop-in replacement compatibility with `aiocsv` while providing true async performance with GIL-independent I/O.
214
+
215
+ ## Contributing
216
+
217
+ Contributions are welcome! Please see our [contributing guidelines](https://github.com/eddiethedean/rapcsv/blob/main/CONTRIBUTING.md) (coming soon).
218
+
219
+ ## License
220
+
221
+ MIT
222
+
223
+ ## Changelog
224
+
225
+ See [CHANGELOG.md](https://github.com/eddiethedean/rapcsv/blob/main/CHANGELOG.md) (coming soon) for version history.
226
+
@@ -0,0 +1,7 @@
1
+ rapcsv/__init__.py,sha256=sMhUUCdC2oVTKMic67GXxx2bs2nyKAvy5jp41aXlKEE,454
2
+ rapcsv/_rapcsv.cpython-38-x86_64-linux-gnu.so,sha256=OXkIqEexG4kGesbeMO8o61S-8as-NEGoOY5bglF10ac,1086888
3
+ rapcsv/_rapcsv.pyi,sha256=kHxUy6naJjUfEBGrM6p6FuOLIyTlJ0Fm2W8IlcYQsF0,353
4
+ rapcsv/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
+ rapcsv-0.0.2.dist-info/METADATA,sha256=gc2lMrQADF-WHhZJptugq70WcKhYb0s4U_iqmLhX6lg,7726
6
+ rapcsv-0.0.2.dist-info/WHEEL,sha256=3N5EpdPBJMYIW1be1E4XQax3kkFUj46lEw0Ks8eIJi4,107
7
+ rapcsv-0.0.2.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: maturin (1.11.5)
3
+ Root-Is-Purelib: false
4
+ Tag: cp38-cp38-manylinux_2_28_x86_64