Skip to content

Commit 207b350

Browse files
pcmoritzpitrou
authored andcommitted
ARROW-5027: [Python] Python bindings for JSON reader
This PR implements Python bindings for the JSON reader. Author: Philipp Moritz <pcmoritz@gmail.com> Closes apache#4044 from pcmoritz/cython-read-json and squashes the following commits: 1148f43 <Philipp Moritz> update 465e9d4 <Philipp Moritz> fixes and docstring d75b02d <Philipp Moritz> add tests b630845 <Philipp Moritz> temp commit aa0aa3f <Philipp Moritz> update b1742b0 <Philipp Moritz> update 9dfc978 <Philipp Moritz> add absolute imports c776e0f <Philipp Moritz> linting bb61428 <Philipp Moritz> comment in again 46a8561 <Philipp Moritz> update 6190645 <Philipp Moritz> update 364971c <Philipp Moritz> update 90a3510 <Philipp Moritz> update 4edb201 <Philipp Moritz> initial work on JSON reader python wrapper
1 parent f82af62 commit 207b350

37 files changed

Lines changed: 456 additions & 1 deletion

‎python/CMakeLists.txt‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ if(UNIX)
378378
set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
379379
endif()
380380

381-
set(CYTHON_EXTENSIONS lib _csv)
381+
set(CYTHON_EXTENSIONS lib _csv _json)
382382

383383
set(LINK_LIBS arrow_shared arrow_python_shared)
384384

‎python/pyarrow/__init__.pxd‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
# specific language governing permissions and limitations
1616
# under the License.
1717

18+
from __future__ import absolute_import
19+
1820
from libcpp.memory cimport shared_ptr
1921
from pyarrow.includes.libarrow cimport (CArray, CBuffer, CColumn, CDataType,
2022
CField, CRecordBatch, CSchema,

‎python/pyarrow/__init__.py‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818
# flake8: noqa
1919

20+
from __future__ import absolute_import
21+
2022
import os as _os
2123
import sys as _sys
2224

‎python/pyarrow/_csv.pyx‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
# cython: embedsignature = True
2121
# cython: language_level = 3
2222

23+
from __future__ import absolute_import
24+
2325
from pyarrow.includes.common cimport *
2426
from pyarrow.includes.libarrow cimport *
2527
from pyarrow.lib cimport (check_status, Field, MemoryPool, ensure_type,

‎python/pyarrow/_cuda.pxd‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818
# cython: language_level = 3
1919

20+
from __future__ import absolute_import
21+
2022
from pyarrow.lib cimport *
2123
from pyarrow.includes.common cimport *
2224
from pyarrow.includes.libarrow cimport *

‎python/pyarrow/_cuda.pyx‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
# under the License.
1717

1818

19+
from __future__ import absolute_import
20+
1921
from pyarrow.compat import tobytes
2022
from pyarrow.lib cimport *
2123
from pyarrow.includes.libarrow_cuda cimport *

‎python/pyarrow/_flight.pyx‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818
# cython: language_level = 3
1919

20+
from __future__ import absolute_import
21+
2022
import collections
2123
import enum
2224

‎python/pyarrow/_json.pyx‎

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The ASF licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing,
12+
# software distributed under the License is distributed on an
13+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
# KIND, either express or implied. See the License for the
15+
# specific language governing permissions and limitations
16+
# under the License.
17+
18+
# cython: profile=False
19+
# distutils: language = c++
20+
# cython: embedsignature = True
21+
# cython: language_level = 3
22+
23+
from __future__ import absolute_import
24+
25+
from pyarrow.includes.common cimport *
26+
from pyarrow.includes.libarrow cimport *
27+
from pyarrow.lib cimport (check_status, Field, MemoryPool, ensure_type,
28+
maybe_unbox_memory_pool, get_input_stream,
29+
pyarrow_wrap_table, pyarrow_wrap_data_type,
30+
pyarrow_unwrap_data_type, pyarrow_wrap_schema,
31+
pyarrow_unwrap_schema)
32+
33+
34+
cdef class ReadOptions:
35+
"""
36+
Options for reading JSON files.
37+
38+
Parameters
39+
----------
40+
use_threads : bool, optional (default True)
41+
Whether to use multiple threads to accelerate reading
42+
block_size : int, optional
43+
How much bytes to process at a time from the input stream.
44+
This will determine multi-threading granularity as well as
45+
the size of individual chunks in the Table.
46+
"""
47+
cdef:
48+
CJSONReadOptions options
49+
50+
# Avoid mistakingly creating attributes
51+
__slots__ = ()
52+
53+
def __init__(self, use_threads=None, block_size=None):
54+
self.options = CJSONReadOptions.Defaults()
55+
if use_threads is not None:
56+
self.use_threads = use_threads
57+
if block_size is not None:
58+
self.block_size = block_size
59+
60+
@property
61+
def use_threads(self):
62+
"""
63+
Whether to use multiple threads to accelerate reading.
64+
"""
65+
return self.options.use_threads
66+
67+
@use_threads.setter
68+
def use_threads(self, value):
69+
self.options.use_threads = value
70+
71+
@property
72+
def block_size(self):
73+
"""
74+
How much bytes to process at a time from the input stream.
75+
This will determine multi-threading granularity as well as
76+
the size of individual chunks in the Table.
77+
"""
78+
return self.options.block_size
79+
80+
@block_size.setter
81+
def block_size(self, value):
82+
self.options.block_size = value
83+
84+
cdef class ParseOptions:
85+
"""
86+
Options for parsing JSON files.
87+
88+
Parameters
89+
----------
90+
explicit_schema: Schema, optional (default None)
91+
Optional explicit schema (no type inference, ignores other fields).
92+
newlines_in_values: bool, optional (default False)
93+
Whether objects may be printed across multiple lines (for example
94+
pretty printed). If false, input must end with an empty line.
95+
"""
96+
97+
cdef:
98+
CJSONParseOptions options
99+
100+
__slots__ = ()
101+
102+
def __init__(self, explicit_schema=None, newlines_in_values=None):
103+
self.options = CJSONParseOptions.Defaults()
104+
if explicit_schema is not None:
105+
self.explicit_schema = explicit_schema
106+
if newlines_in_values is not None:
107+
self.newlines_in_values = newlines_in_values
108+
109+
@property
110+
def explicit_schema(self):
111+
"""
112+
Optional explicit schema (no type inference, ignores other fields)
113+
"""
114+
if self.options.explicit_schema.get() == NULL:
115+
return None
116+
else:
117+
return pyarrow_wrap_schema(self.options.explicit_schema)
118+
119+
@explicit_schema.setter
120+
def explicit_schema(self, value):
121+
self.options.explicit_schema = pyarrow_unwrap_schema(value)
122+
123+
@property
124+
def newlines_in_values(self):
125+
"""
126+
Whether newline characters are allowed in JSON values.
127+
Setting this to True reduces the performance of multi-threaded
128+
JSON reading.
129+
"""
130+
return self.options.newlines_in_values
131+
132+
@newlines_in_values.setter
133+
def newlines_in_values(self, value):
134+
self.options.newlines_in_values = value
135+
136+
137+
cdef _get_reader(input_file, shared_ptr[InputStream]* out):
138+
use_memory_map = False
139+
get_input_stream(input_file, use_memory_map, out)
140+
141+
cdef _get_read_options(ReadOptions read_options, CJSONReadOptions* out):
142+
if read_options is None:
143+
out[0] = CJSONReadOptions.Defaults()
144+
else:
145+
out[0] = read_options.options
146+
147+
cdef _get_parse_options(ParseOptions parse_options, CJSONParseOptions* out):
148+
if parse_options is None:
149+
out[0] = CJSONParseOptions.Defaults()
150+
else:
151+
out[0] = parse_options.options
152+
153+
154+
def read_json(input_file, read_options=None, parse_options=None,
155+
MemoryPool memory_pool=None):
156+
"""
157+
Read a Table from a stream of JSON data.
158+
159+
Parameters
160+
----------
161+
input_file: string, path or file-like object
162+
The location of JSON data.
163+
read_options: ReadOptions, optional
164+
Options for the JSON reader (see ReadOptions constructor for defaults)
165+
parse_options: ParseOptions, optional
166+
Options for the JSON parser
167+
(see ParseOptions constructor for defaults)
168+
memory_pool: MemoryPool, optional
169+
Pool to allocate Table memory from
170+
171+
Returns
172+
-------
173+
:class:`pyarrow.Table`
174+
Contents of the JSON file as a in-memory table.
175+
"""
176+
cdef:
177+
shared_ptr[InputStream] stream
178+
CJSONReadOptions c_read_options
179+
CJSONParseOptions c_parse_options
180+
shared_ptr[CJSONReader] reader
181+
shared_ptr[CTable] table
182+
183+
_get_reader(input_file, &stream)
184+
_get_read_options(read_options, &c_read_options)
185+
_get_parse_options(parse_options, &c_parse_options)
186+
187+
check_status(CJSONReader.Make(maybe_unbox_memory_pool(memory_pool),
188+
stream, c_read_options, c_parse_options,
189+
&reader))
190+
191+
with nogil:
192+
check_status(reader.get().Read(&table))
193+
194+
return pyarrow_wrap_table(table)

‎python/pyarrow/_orc.pxd‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
# distutils: language = c++
1919
# cython: language_level = 3
2020

21+
from __future__ import absolute_import
22+
2123
from libc.string cimport const_char
2224
from libcpp.vector cimport vector as std_vector
2325
from pyarrow.includes.common cimport *

‎python/pyarrow/_orc.pyx‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
# distutils: language = c++
2020
# cython: embedsignature = True
2121

22+
from __future__ import absolute_import
23+
2224
from cython.operator cimport dereference as deref
2325
from libcpp.vector cimport vector as std_vector
2426
from pyarrow.includes.common cimport *

0 commit comments

Comments
 (0)