Skip to content

Commit 8a20605

Browse files
authored
Merge pull request #36 from marklogic/feature/format-rows
Formatted rows.py and its tests
2 parents ac99919 + 827d629 commit 8a20605

File tree

3 files changed

+67
-36
lines changed

3 files changed

+67
-36
lines changed

marklogic/rows.py

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import json
2-
from requests import Session, Response
2+
from requests import Session
33

44
"""
55
Defines a RowManager class to simplify usage of the "/v1/rows" & "/v1/rows/graphql" REST
@@ -15,7 +15,9 @@ class RowManager:
1515
def __init__(self, session: Session):
1616
self._session = session
1717

18-
def graphql(self, graphql_query: str, return_response: bool = False, *args, **kwargs):
18+
def graphql(
19+
self, graphql_query: str, return_response: bool = False, *args, **kwargs
20+
):
1921
"""
2022
Send a GraphQL query to MarkLogic via a POST to the endpoint defined at
2123
https://docs.marklogic.com/REST/POST/v1/rows/graphql
@@ -48,18 +50,28 @@ def graphql(self, graphql_query: str, return_response: bool = False, *args, **kw
4850
"xml": "application/xml",
4951
"csv": "text/csv",
5052
"json-seq": "application/json-seq",
51-
"mixed": "application/xml, multipart/mixed"
53+
"mixed": "application/xml, multipart/mixed",
5254
}
5355

5456
__query_format_switch = {
5557
"json": lambda response: response.json(),
5658
"xml": lambda response: response.text,
5759
"csv": lambda response: response.text,
5860
"json-seq": lambda response: response.text,
59-
"mixed": lambda response: response
61+
"mixed": lambda response: response,
6062
}
6163

62-
def query(self, dsl: str = None, plan: dict = None, sql: str = None, sparql: str = None, format: str = "json", return_response: bool = False, *args, **kwargs):
64+
def query(
65+
self,
66+
dsl: str = None,
67+
plan: dict = None,
68+
sql: str = None,
69+
sparql: str = None,
70+
format: str = "json",
71+
return_response: bool = False,
72+
*args,
73+
**kwargs
74+
):
6375
"""
6476
Send a query to MarkLogic via a POST to the endpoint defined at
6577
https://docs.marklogic.com/REST/POST/v1/rows
@@ -86,10 +98,7 @@ def query(self, dsl: str = None, plan: dict = None, sql: str = None, sparql: str
8698
headers["Content-Type"] = request_info["content-type"]
8799
headers["Accept"] = RowManager.__accept_switch.get(format)
88100
response = self._session.post(
89-
"v1/rows",
90-
headers=headers,
91-
data=request_info["data"],
92-
**kwargs
101+
"v1/rows", headers=headers, data=request_info["data"], **kwargs
93102
)
94103
return (
95104
RowManager.__query_format_switch.get(format)(response)
@@ -111,22 +120,15 @@ def __get_request_info(self, dsl: str, plan: dict, sql: str, sparql: str):
111120
if dsl is not None:
112121
return {
113122
"content-type": "application/vnd.marklogic.querydsl+javascript",
114-
"data": dsl
123+
"data": dsl,
115124
}
116125
if plan is not None:
117-
return {
118-
"content-type": "application/json",
119-
"data": plan
120-
}
126+
return {"content-type": "application/json", "data": plan}
121127
if sql is not None:
122-
return {
123-
"content-type": "application/sql",
124-
"data": sql
125-
}
128+
return {"content-type": "application/sql", "data": sql}
126129
if sparql is not None:
127-
return {
128-
"content-type": "application/sparql-query",
129-
"data": sparql
130-
}
130+
return {"content-type": "application/sparql-query", "data": sparql}
131131
else:
132-
raise ValueError("No query found; must specify one of: dsl, plan, sql, or sparql")
132+
raise ValueError(
133+
"No query found; must specify one of: dsl, plan, sql, or sparql"
134+
)

tests/test_graphql.py

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
def test_graphql(client):
2-
data = client.rows.graphql("query musicianQuery { test_musician { lastName firstName dob } }")
2+
data = client.rows.graphql(
3+
"query musicianQuery { test_musician { lastName firstName dob } }"
4+
)
35
musicians = data["data"]["test_musician"]
46
assert 4 == len(musicians)
57
assert 1 == len([m for m in musicians if m["lastName"] == "Armstrong"])
68

79

810
def test_graphql_return_response(client):
9-
response = client.rows.graphql("query musicianQuery { test_musician { lastName firstName dob } }", return_response=True)
11+
response = client.rows.graphql(
12+
"query musicianQuery { test_musician { lastName firstName dob } }",
13+
return_response=True,
14+
)
1015
assert 200 == response.status_code
1116
data = response.json()
1217
musicians = data["data"]["test_musician"]
@@ -15,11 +20,18 @@ def test_graphql_return_response(client):
1520

1621

1722
def test_graphql_bad_graphql(client):
18-
response = client.rows.graphql("query musicianQuery { test_musician { lastName firstName dob } ")
19-
assert 1 == len(response['errors'])
20-
assert 'GRAPHQL-PARSE: Error parsing the GraphQL request string => \nquery musicianQuery { test_musician { lastName firstName dob } ' == response['errors'][0]['message']
23+
response = client.rows.graphql(
24+
"query musicianQuery { test_musician { lastName firstName dob } "
25+
)
26+
assert 1 == len(response["errors"])
27+
assert (
28+
"GRAPHQL-PARSE: Error parsing the GraphQL request string => \nquery musicianQuery { test_musician { lastName firstName dob } "
29+
== response["errors"][0]["message"]
30+
)
2131

2232

2333
def test_graphql_bad_user(not_rest_user_client):
24-
response = not_rest_user_client.rows.graphql("query musicianQuery { test_musician { lastName firstName dob } }")
34+
response = not_rest_user_client.rows.graphql(
35+
"query musicianQuery { test_musician { lastName firstName dob } }"
36+
)
2537
assert 403 == response.status_code

tests/test_query.py renamed to tests/test_rows.py

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
dsl_query = 'op.fromView("test","musician").orderBy(op.col("lastName"))'
44
serialized_query = '{"$optic":{"ns":"op", "fn":"operators", "args":[{"ns":"op", "fn":"from-view", "args":["test", "musician"]}, {"ns":"op", "fn":"order-by", "args":[{"ns":"op", "fn":"col", "args":["lastName"]}]}]}}'
5-
sql_query = 'select * from musician order by lastName'
6-
sparql_query = 'PREFIX musician: <http://marklogic.com/column/test/musician/> SELECT * WHERE {?s musician:lastName ?lastName} ORDER BY ?lastName'
5+
sql_query = "select * from musician order by lastName"
6+
sparql_query = "PREFIX musician: <http://marklogic.com/column/test/musician/> SELECT * WHERE {?s musician:lastName ?lastName} ORDER BY ?lastName"
77

88

99
def test_dsl_default(client):
@@ -14,7 +14,9 @@ def test_dsl_default(client):
1414
def test_dsl_default_return_response(client):
1515
response = client.rows.query(dsl_query, return_response=True)
1616
assert 200 == response.status_code
17-
verify_four_musicians_are_returned_in_json(response.json(), "test.musician.lastName")
17+
verify_four_musicians_are_returned_in_json(
18+
response.json(), "test.musician.lastName"
19+
)
1820

1921

2022
def test_query_bad_user(not_rest_user_client):
@@ -31,17 +33,22 @@ def test_dsl_xml(client):
3133
data = client.rows.query(dsl_query, format="xml")
3234
verify_four_musicians_are_returned_in_xml_string(data)
3335

36+
3437
def test_dsl_csv(client):
3538
data = client.rows.query(dsl_query, format="csv")
3639
verify_four_musicians_are_returned_in_csv(data)
3740

41+
3842
def test_dsl_json_seq(client):
3943
data = client.rows.query(dsl_query, format="json-seq")
4044
verify_four_musicians_are_returned_in_json_seq(data)
4145

46+
4247
def test_dsl_mixed(client):
4348
response = client.rows.query(dsl_query, format="mixed")
44-
verify_four_musicians_are_returned_in_json(response.json(), "test.musician.lastName")
49+
verify_four_musicians_are_returned_in_json(
50+
response.json(), "test.musician.lastName"
51+
)
4552

4653

4754
def test_serialized_default(client):
@@ -60,15 +67,20 @@ def test_sparql_default(client):
6067

6168

6269
def test_no_query_parameter_provided(client):
63-
with raises(ValueError, match="No query found; must specify one of: dsl, plan, sql, or sparql"):
70+
with raises(
71+
ValueError,
72+
match="No query found; must specify one of: dsl, plan, sql, or sparql",
73+
):
6474
client.rows.query()
6575

6676

6777
def verify_four_musicians_are_returned_in_json(data, column_name):
6878
assert type(data) is dict
6979
assert 4 == len(data["rows"])
7080
for index, musician in enumerate(["Armstrong", "Byron", "Coltrane", "Davis"]):
71-
assert {'type': 'xs:string', 'value': musician} == data["rows"][index][column_name]
81+
assert {"type": "xs:string", "value": musician} == data["rows"][index][
82+
column_name
83+
]
7284

7385

7486
def verify_four_musicians_are_returned_in_xml_string(data):
@@ -81,7 +93,12 @@ def verify_four_musicians_are_returned_in_xml_string(data):
8193
def verify_four_musicians_are_returned_in_csv(data):
8294
assert type(data) is str
8395
assert 5 == len(data.split("\n"))
84-
for musician in ['Armstrong,Louis,1901-08-04', 'Byron,Don,1958-11-08', 'Coltrane,John,1926-09-23', 'Davis,Miles,1926-05-26']:
96+
for musician in [
97+
"Armstrong,Louis,1901-08-04",
98+
"Byron,Don,1958-11-08",
99+
"Coltrane,John,1926-09-23",
100+
"Davis,Miles,1926-05-26",
101+
]:
85102
assert musician in data
86103

87104

0 commit comments

Comments
 (0)