Skip to content

Commit 8dbd8be

Browse files
authored
Merge pull request #16 from marklogic/feature/514-read-write-docs
DEVEXP-514 Added docs for reading, writing, and searching
2 parents a191226 + 409e743 commit 8dbd8be

File tree

10 files changed

+507
-30
lines changed

10 files changed

+507
-30
lines changed

docs/getting-started.md

Lines changed: 58 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -9,73 +9,100 @@ MarkLogic Python client into a Python virtual environment.
99

1010
## Connecting to MarkLogic
1111

12-
(TODO This will almost certainly be reorganized before the 1.0 release.)
13-
1412
The `Client` class is the primary API to interact with in the MarkLogic Python client. The
1513
`Client` class extends the `requests`
1614
[`Session` class](https://docs.python-requests.org/en/latest/user/advanced/#session-objects), thus exposing all methods
1715
found in both the `Session` class and the `requests` API. You can therefore use a `Client` object in the same manner
1816
as you'd use either the `Session` class or the `requests` API.
1917

18+
To try out any of the examples below or in the rest of this guide, you will first need to create a new MarkLogic user.
19+
To do so, please go to the Admin application for your MarkLogic instance - e.g. if you are running MarkLogic locally,
20+
this will be at <http://localhost:8001>, and you will authenticate as your "admin" user. Then perform the following
21+
steps to create a new user:
22+
23+
1. Click on "Users" in the "Security" box.
24+
2. Click on "Create".
25+
3. In the form, enter "python-user" for "User Name" and "pyth0n" as the password.
26+
4. Scroll down until you see the "Roles" section. Click on the "rest-reader" and "rest-writer" checkboxes.
27+
5. Scroll to the top or bottom and click on "OK" to create the user.
28+
2029
A `Client` instance can be constructed either by providing a base URL for all requests along with authentication:
2130

22-
from marklogic import Client
23-
client = Client('http://localhost:8030', digest=('username', 'password'))
31+
```
32+
from marklogic import Client
33+
client = Client('http://localhost:8000', digest=('python-user', 'pyth0n'))
34+
```
2435

2536
Or via separate arguments for each of the parts of a base URL:
2637

27-
from marklogic import Client
28-
client = Client(host='localhost', port='8030', digest=('username', 'password'))
38+
```
39+
from marklogic import Client
40+
client = Client(host='localhost', port='8000', digest=('python-user', 'pyth0n'))
41+
```
2942

3043
After constructing a `Client` instance, each of the methods in the `requests` API for sending an HTTP request can be
3144
used without needing to specify the base URL nor the authentication again. For example:
3245

33-
response = client.post('/v1/search')
34-
response = client.get('/v1/documents', params={'uri': '/my-doc.json'})
46+
```
47+
response = client.post('/v1/search')
48+
response = client.get('/v1/documents', params={'uri': '/my-doc.json'})
49+
```
3550

3651
Because the `Client` class extends the `Sessions` class, it can be used as a context manager:
3752

38-
with Client('http://localhost:8030', digest=('username', 'password')) as client:
39-
response = client.post('/v1/search')
40-
response = client.get('/v1/documents', params={'uri': '/my-doc.json'})
53+
```
54+
with Client('http://localhost:8000', digest=('python-user', 'pyth0n')) as client:
55+
response = client.post('/v1/search')
56+
response = client.get('/v1/documents', params={'uri': '/my-doc.json'})
57+
```
4158

4259
## Authentication
4360

4461
The `Client` constructor includes a `digest` argument as a convenience for using digest authentication:
4562

46-
from marklogic import Client
47-
client = Client('http://localhost:8030', digest=('username', 'password'))
63+
```
64+
from marklogic import Client
65+
client = Client('http://localhost:8000', digest=('python-user', 'pyth0n'))
66+
```
4867

4968
An `auth` argument is also available for using any authentication strategy that can be configured
5069
[via the requests `auth` argument](https://requests.readthedocs.io/en/latest/user/advanced/#custom-authentication). For
5170
example, just like with `requests`, a tuple can be passed to the `auth` argument to use basic authentication:
5271

53-
from marklogic import Client
54-
client = Client('http://localhost:8030', auth=('username', 'password'))
72+
```
73+
from marklogic import Client
74+
client = Client('http://localhost:8000', auth=('python-user', 'pyth0n'))
75+
```
5576

5677
### MarkLogic Cloud Authentication
5778

5879
When connecting to a [MarkLogic Cloud instance](https://developer.marklogic.com/products/cloud/), you will need to set
5980
the `cloud_api_key` and `base_path` arguments. You only need to specify a `host` as well, as port 443 and HTTPS will be
6081
used by default. For example:
6182

62-
from marklogic import Client
63-
client = Client(host='example.marklogic.cloud', cloud_api_key='some-key-value', base_path='/ml/example/manage')
83+
```
84+
from marklogic import Client
85+
client = Client(host='example.marklogic.cloud', cloud_api_key='some-key-value', base_path='/ml/example/manage')
86+
```
6487

6588
You may still use a full base URL if you wish:
6689

67-
from marklogic import Client
68-
client = Client('https://example.marklogic.cloud', cloud_api_key='some-key-value', base_path='/ml/example/manage')
90+
```
91+
from marklogic import Client
92+
client = Client('https://example.marklogic.cloud', cloud_api_key='some-key-value', base_path='/ml/example/manage')
93+
```
6994

7095
MarkLogic Cloud uses an access token for authentication; the access token is generated using the API key value. In some
7196
scenarios, you may wish to set the token expiration time to a value other than the default used by MarkLogic Cloud. To
7297
do so, set the `cloud_token_duration` argument to a number greater than zero that defines the token duration in
7398
minutes:
7499

75-
from marklogic import Client
76-
# Sets a token duration of 10 minutes.
77-
client = Client(host='example.marklogic.cloud', cloud_api_key='some-key-value', base_path='/ml/example/manage',
78-
cloud_token_duration=10)
100+
```
101+
from marklogic import Client
102+
# Sets a token duration of 10 minutes.
103+
client = Client(host='example.marklogic.cloud', cloud_api_key='some-key-value', base_path='/ml/example/manage',
104+
cloud_token_duration=10)
105+
```
79106

80107
## SSL
81108

@@ -84,10 +111,14 @@ Configuring SSL connections is the same as
84111
As a convience, the `Client` constructor includes a `verify` argument so that it does not need to be configured on the
85112
`Client` instance after it's been constructed nor on every request:
86113

87-
from marklogic import Client
88-
client = Client('https://localhost:8030', digest=('username', 'password'), verify='/path/to/cert.pem')
114+
```
115+
from marklogic import Client
116+
client = Client('https://localhost:8000', digest=('python-user', 'pyth0n'), verify='/path/to/cert.pem')
117+
```
89118

90119
When specifying the base URL via separate arguments, the `scheme` argument can be set for HTTPS connections:
91120

92-
from marklogic import Client
93-
client = Client(host='localhost', port='8030', scheme='https', digest=('username', 'password'), verify=False)
121+
```
122+
from marklogic import Client
123+
client = Client(host='localhost', port='8000', scheme='https', digest=('python-user', 'pyth0n'), verify=False)
124+
```

docs/index.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,6 @@ nav_order: 1
77
The MarkLogic Python Client further simplifies usage of the
88
[Python `requests` library](https://pypi.org/project/requests/) when developing applications in Python that communicate
99
with the [MarkLogic REST API](https://docs.marklogic.com/guide/rest-dev).
10+
11+
See the [Getting Started guide](getting-started.md) to begin using the client.
12+
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
---
2+
layout: default
3+
title: Managing Documents
4+
nav_order: 3
5+
has_children: true
6+
permalink: /docs/managing-documents
7+
---
8+
9+
The [/v1/documents endpoint](https://docs.marklogic.com/REST/client/management) in the MarkLogic REST API simplifies
10+
operations that involve writing or reading a single document. It also supports operations that involve multiple
11+
documents, though those require use of a potentially complex multipart HTTP request or response. The MarkLogic Python
12+
client simplifies those operations by hiding the details of multipart requests and responses.
13+
14+
## Setup for examples
15+
16+
The examples shown in [Reading Documents](reading.md) and [Searching Documents](searching.md) assume that you have
17+
created a new MarkLogic user named "python-user" as described in the [Getting Started](getting-started.md) guide.
18+
The examples also depend on documents being created by the below script. If you would like to run each of the examples,
19+
please run the script below, which will create a `Client` instance that interacts with the out-of-the-box "Documents"
20+
database in MarkLogic.
21+
22+
```
23+
from marklogic import Client
24+
from marklogic.documents import Document, DefaultMetadata
25+
26+
client = Client('http://localhost:8000', digest=('python-user', 'pyth0n'))
27+
client.documents.write([
28+
DefaultMetadata(permissions={"rest-reader": ["read", "update"]}, collections=["python-example"]),
29+
Document("/doc1.json", {"text": "example one"}),
30+
Document("/doc2.json", {"text": "example two"})
31+
])
32+
```

docs/managing-documents/reading.md

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
---
2+
layout: default
3+
title: Reading Documents
4+
parent: Managing Documents
5+
nav_order: 3
6+
---
7+
8+
The [GET /v1/documents](https://docs.marklogic.com/REST/GET/v1/documents) endpoint in the MarkLogic REST API supports
9+
reading multiple documents with metadata via a multipart/mixed HTTP response. The MarkLogic Python client simplifies
10+
handling the response by converting it into a list of `Document` instances via the `client.documents.read` method.
11+
12+
## Setup for examples
13+
14+
The examples below all assume that you have created a new MarkLogic user named "python-user" as described in the
15+
[Getting Started](getting-started.md) guide. To run these examples, please run the following script first, which will
16+
create a `Client` instance that interacts with the out-of-the-box "Documents" database in MarkLogic:
17+
```
18+
from marklogic import Client
19+
from marklogic.documents import Document, DefaultMetadata
20+
21+
client = Client('http://localhost:8000', digest=('python-user', 'pyth0n'))
22+
client.documents.write([
23+
DefaultMetadata(permissions={"rest-reader": ["read", "update"]}, collections=["python-example"]),
24+
Document("/doc1.json", {"text": "example one"}),
25+
Document("/doc2.xml", "<text>example two</text>"),
26+
Document("/doc3.bin", b"binary example", permissions={"rest-reader": ["read", "update"]})
27+
])
28+
```
29+
30+
## Reading documents
31+
32+
A list of `Document` instances can be obtained for a list of URIs, where each `Document` has its `uri` and `content`
33+
attributes populated but no metadata by default:
34+
35+
```
36+
docs = client.documents.read(["/doc1.json", "/doc2.xml", "/doc3.bin"])
37+
assert len(docs) == 3
38+
```
39+
40+
The [requests toolbelt](https://toolbelt.readthedocs.io/en/latest/) library is used to process the multipart
41+
HTTP response returned by MarkLogic. By default, the `content` attribute of each `Document` will be a binary value.
42+
The client will convert this into something more useful based on the content types in the table below:
43+
44+
| Content type | `content` attribute type |
45+
| --- | --- |
46+
| application/json | dictionary |
47+
| application/xml | string |
48+
| text/xml | string |
49+
| text/plain | string |
50+
51+
Thus, the `Document` with a URI of "/doc1.json" will have a dictionary as the value of its
52+
`content` attribute. The `Document` with a URI of "/doc2.xml" will have a string as the value of its `content`
53+
attribute. And the `Docuemnt` with a URI of "/doc3.bin" will have a binary value for its `content` attribute.
54+
55+
A `Document` instance can be examined simply by printing or logging it; this will display all of the instance's
56+
changeable attributes, including the URI, content, and metadata:
57+
58+
```
59+
doc = docs[0]
60+
print(doc)
61+
62+
# Can always built-in Python vars method.
63+
print(vars(doc))
64+
```
65+
66+
## Reading documents with metadata
67+
68+
Metadata for each document can be retrieved via the `categories` argument. The acceptable values for this argument
69+
match those of the `category` parameter in the [GET /v1/documents](https://docs.marklogic.com/REST/GET/v1/documents)
70+
documentation: `content`, `metadata`, `metadata-values`, `collections`, `permissions`, `properties`, and `quality`.
71+
72+
The following shows different examples of configuring the `categories` argument:
73+
74+
```
75+
uris = ["/doc1.json", "/doc2.xml", "/doc3.bin"]
76+
77+
# Retrieve content and all metadata for each document.
78+
docs = client.documents.read(uris, categories=["content", "metadata"])
79+
print(docs)
80+
81+
# Retrieve content, collections, and permissions for each document.
82+
docs = client.documents.read(uris, categories=["content", "collections", "permissions"])
83+
print(docs)
84+
85+
# Retrieve only collections for each document; the content attribute will be None.
86+
docs = client.documents.read(uris, categories=["collections"])
87+
print(docs)
88+
```
89+
90+
# Error handling
91+
92+
A GET call to the /v1/documents endpoint in MarkLogic will return an HTTP response with a status code of 200 for a
93+
successful request. For any other status code, the `client.documents.read` method will the `requests` `Response` object,
94+
providing access to the error details returned by MarkLogic.

0 commit comments

Comments
 (0)