Skip to content

Commit e16f448

Browse files
author
Ilyas Gasanov
committed
[DOP-21442] Add Excel API schema
1 parent 32726c9 commit e16f448

File tree

8 files changed

+116
-19
lines changed

8 files changed

+116
-19
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add Excel API schema

syncmaster/schemas/v1/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
PostgresReadTransferSourceAndTarget,
3737
ReadDBTransfer,
3838
)
39-
from syncmaster.schemas.v1.transfers.file_format import CSV, JSON, JSONLine
39+
from syncmaster.schemas.v1.transfers.file_format import CSV, JSON, Excel, JSONLine
4040
from syncmaster.schemas.v1.transfers.run import (
4141
CreateRunSchema,
4242
ReadRunSchema,

syncmaster/schemas/v1/file_formats.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@
55
CSV_FORMAT = Literal["csv"]
66
JSONLINE_FORMAT = Literal["jsonline"]
77
JSON_FORMAT = Literal["json"]
8+
EXCEL_FORMAT = Literal["excel"]

syncmaster/schemas/v1/transfers/file/base.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,28 +7,28 @@
77

88
from pydantic import BaseModel, Field, field_validator
99

10-
from syncmaster.schemas.v1.transfers.file_format import CSV, JSON, JSONLine
10+
from syncmaster.schemas.v1.transfers.file_format import CSV, JSON, Excel, JSONLine
1111

1212

1313
# At the moment the ReadTransferSourceParams and ReadTransferTargetParams
1414
# classes are identical but may change in the future
1515
class ReadFileTransferSource(BaseModel):
1616
directory_path: str
17-
file_format: CSV | JSONLine | JSON = Field(..., discriminator="type")
17+
file_format: CSV | JSONLine | JSON | Excel = Field(..., discriminator="type")
1818
options: dict[str, Any]
1919

2020

2121
class ReadFileTransferTarget(BaseModel):
2222
directory_path: str
23-
file_format: CSV | JSONLine = Field(..., discriminator="type") # JSON format is not supported for writing
23+
file_format: CSV | JSONLine | Excel = Field(..., discriminator="type") # JSON format is not supported for writing
2424
options: dict[str, Any]
2525

2626

2727
# At the moment the CreateTransferSourceParams and CreateTransferTargetParams
2828
# classes are identical but may change in the future
2929
class CreateFileTransferSource(BaseModel):
3030
directory_path: str
31-
file_format: CSV | JSONLine | JSON = Field(..., discriminator="type")
31+
file_format: CSV | JSONLine | JSON | Excel = Field(..., discriminator="type")
3232
options: dict[str, Any] = Field(default_factory=dict)
3333

3434
class Config:
@@ -44,7 +44,7 @@ def _directory_path_is_valid_path(cls, value):
4444

4545
class CreateFileTransferTarget(BaseModel):
4646
directory_path: str
47-
file_format: CSV | JSONLine = Field(..., discriminator="type") # JSON FORMAT IS NOT SUPPORTED AS A TARGET !
47+
file_format: CSV | JSONLine | Excel = Field(..., discriminator="type") # JSON FORMAT IS NOT SUPPORTED AS A TARGET !
4848
options: dict[str, Any] = Field(default_factory=dict)
4949

5050
class Config:

syncmaster/schemas/v1/transfers/file_format.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@
44

55
from pydantic import BaseModel
66

7-
from syncmaster.schemas.v1.file_formats import CSV_FORMAT, JSON_FORMAT, JSONLINE_FORMAT
7+
from syncmaster.schemas.v1.file_formats import (
8+
CSV_FORMAT,
9+
EXCEL_FORMAT,
10+
JSON_FORMAT,
11+
JSONLINE_FORMAT,
12+
)
813

914

1015
class CSV(BaseModel):
@@ -27,3 +32,9 @@ class JSON(BaseModel):
2732
type: JSON_FORMAT
2833
encoding: str = "utf-8"
2934
line_sep: str = "\n"
35+
36+
37+
class Excel(BaseModel):
38+
type: EXCEL_FORMAT
39+
include_header: bool
40+
start_cell: str | None = None

tests/test_unit/test_transfers/test_file_transfers/test_create_transfer.py

Lines changed: 73 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,24 @@
2828
"directory_path": "/some/pure/path",
2929
"file_format": {
3030
"type": "csv",
31+
"delimiter": ",",
32+
"encoding": "utf-8",
33+
"quote": '"',
34+
"escape": "\\",
35+
"header": False,
36+
"line_sep": "\n",
37+
},
38+
"options": {
39+
"some": "option",
40+
},
41+
},
42+
{
43+
"type": "s3",
44+
"directory_path": "/some/excel/path",
45+
"file_format": {
46+
"type": "excel",
47+
"include_header": True,
48+
"start_cell": "A1",
3149
},
3250
"options": {
3351
"some": "option",
@@ -94,11 +112,26 @@ async def test_developer_plus_can_create_s3_transfer(
94112
"queue_id": transfer.queue_id,
95113
}
96114

115+
expected_file_formats = {
116+
"csv": {
117+
"delimiter": ",",
118+
"encoding": "utf-8",
119+
"quote": '"',
120+
"escape": "\\",
121+
"header": False,
122+
"line_sep": "\n",
123+
},
124+
"excel": {
125+
"include_header": True,
126+
"start_cell": "A1",
127+
},
128+
}
129+
97130
for params in (transfer.source_params, transfer.target_params):
98-
assert params["type"] == "s3"
99-
assert params["directory_path"] == "/some/pure/path"
100-
assert params["file_format"]["type"] == "csv"
131+
assert params["type"] == target_source_params["type"]
132+
assert params["directory_path"] == target_source_params["directory_path"]
101133
assert params["options"] == {"some": "option"}
134+
assert params["file_format"] == expected_file_formats[params["type"]]
102135

103136

104137
@pytest.mark.parametrize(
@@ -121,6 +154,15 @@ async def test_developer_plus_can_create_s3_transfer(
121154
"type": "csv",
122155
},
123156
},
157+
{
158+
"type": "hdfs",
159+
"directory_path": "/some/excel/path",
160+
"file_format": {
161+
"type": "excel",
162+
"include_header": True,
163+
"start_cell": "A1",
164+
},
165+
},
124166
],
125167
)
126168
async def test_developer_plus_can_create_hdfs_transfer(
@@ -183,10 +225,27 @@ async def test_developer_plus_can_create_hdfs_transfer(
183225
"queue_id": transfer.queue_id,
184226
}
185227

228+
expected_file_formats = {
229+
"csv": {
230+
"type": "csv",
231+
"delimiter": ",",
232+
"encoding": "utf-8",
233+
"quote": '"',
234+
"escape": "\\",
235+
"header": False,
236+
"line_sep": "\n",
237+
},
238+
"excel": {
239+
"type": "excel",
240+
"include_header": True,
241+
"start_cell": "A1",
242+
},
243+
}
244+
186245
for params in (transfer.source_params, transfer.target_params):
187-
assert params["type"] == "hdfs"
188-
assert params["directory_path"] == "/some/pure/path"
189-
assert params["file_format"]["type"] == "csv"
246+
assert params["type"] == target_source_params["type"]
247+
assert params["directory_path"] == target_source_params["directory_path"]
248+
assert params["file_format"] == expected_file_formats[params["file_format"]["type"]]
190249
assert params["options"] == {}
191250

192251

@@ -211,6 +270,14 @@ async def test_developer_plus_can_create_hdfs_transfer(
211270
"type": "csv",
212271
},
213272
},
273+
{
274+
"type": "s3",
275+
"directory_path": "some/path",
276+
"file_format": {
277+
"type": "excel",
278+
"include_header": True,
279+
},
280+
},
214281
],
215282
)
216283
async def test_cannot_create_file_transfer_with_relative_path(

tests/test_unit/test_transfers/test_file_transfers/test_read_transfer.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,16 @@
2323
},
2424
"options": {},
2525
},
26+
{
27+
"type": "s3",
28+
"directory_path": "/some/excel/path",
29+
"file_format": {
30+
"type": "excel",
31+
"include_header": True,
32+
"start_cell": "A1",
33+
},
34+
"options": {},
35+
},
2636
],
2737
)
2838
@pytest.mark.parametrize(

tests/test_unit/test_transfers/test_file_transfers/test_update_transfer.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,16 @@
2323
},
2424
"options": {},
2525
},
26+
{
27+
"type": "s3",
28+
"directory_path": "/some/excel/path",
29+
"file_format": {
30+
"type": "excel",
31+
"include_header": True,
32+
"start_cell": "A1",
33+
},
34+
"options": {},
35+
},
2636
],
2737
)
2838
@pytest.mark.parametrize(
@@ -54,7 +64,7 @@ async def test_developer_plus_can_update_s3_transfer(
5464
"source_params": {
5565
"type": "s3",
5666
"directory_path": "/some/new/test/directory",
57-
"file_format": {"type": "jsonline"},
67+
"file_format": create_transfer_data["file_format"],
5868
"options": {"some": "option"},
5969
},
6070
},
@@ -65,14 +75,11 @@ async def test_developer_plus_can_update_s3_transfer(
6575
source_params.update(
6676
{
6777
"directory_path": "/some/new/test/directory",
68-
"file_format": {
69-
"encoding": "utf-8",
70-
"line_sep": "\n",
71-
"type": "jsonline",
72-
},
78+
"file_format": create_transfer_data["file_format"],
7379
"options": {"some": "option"},
7480
},
7581
)
82+
7683
# Assert
7784
assert result.status_code == 200
7885
assert result.json() == {

0 commit comments

Comments
 (0)