• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

collective / sphinxcontrib-httpexample / 10440402089

18 Aug 2024 12:01PM UTC coverage: 94.03%. Remained the same
10440402089

Pull #100

github

web-flow
Bump certifi from 2021.10.8 to 2024.7.4 in /nix

Bumps [certifi](https://github.com/certifi/python-certifi) from 2021.10.8 to 2024.7.4.
- [Commits](https://github.com/certifi/python-certifi/compare/2021.10.08...2024.07.04)

---
updated-dependencies:
- dependency-name: certifi
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Pull Request #100: Bump certifi from 2021.10.8 to 2024.7.4 in /nix

441 of 469 relevant lines covered (94.03%)

14.07 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

99.15
/src/sphinxcontrib/httpexample/directives.py
1
# -*- coding: utf-8 -*-
2
from docutils import nodes
15✔
3
from docutils.parsers.rst import directives
15✔
4
from docutils.statemachine import StringList
15✔
5
from sphinx.directives.code import CodeBlock
15✔
6
from sphinxcontrib.httpexample import builders
15✔
7
from sphinxcontrib.httpexample import parsers
15✔
8
from sphinxcontrib.httpexample import utils
15✔
9

10
import os
15✔
11
import re
15✔
12

13

14
AVAILABLE_BUILDERS = {
15✔
15
    'curl': (builders.build_curl_command, 'bash'),
16
    'wget': (builders.build_wget_command, 'bash'),
17
    'httpie': (builders.build_httpie_command, 'bash'),
18
    'requests': (builders.build_requests_command, 'python'),
19
    'python-requests': (builders.build_requests_command, 'python'),
20
    'plone-javascript': (builders.build_plone_javascript_command, 'javascript'),
21
}
22

23
AVAILABLE_FIELDS = ['query']
15✔
24

25

26
def choose_builders(arguments):
15✔
27
    return [
15✔
28
        directives.choice(argument, AVAILABLE_BUILDERS)
29
        for argument in (arguments or [])
30
    ]
31

32

33
class HTTPExample(CodeBlock):
15✔
34

35
    required_arguments = 0
15✔
36
    optional_arguments = len(AVAILABLE_BUILDERS)
15✔
37

38
    option_spec = utils.merge_dicts(
15✔
39
        CodeBlock.option_spec,
40
        {
41
            'request': directives.unchanged,
42
            'response': directives.unchanged,
43
        },
44
    )
45

46
    @staticmethod
15✔
47
    def process_content(content):
15✔
48
        if content:
15✔
49
            raw = ('\r\n'.join(content)).encode('utf-8')
15✔
50
            request = parsers.parse_request(raw)
15✔
51
            params, _ = request.extract_fields('query')
15✔
52
            params = [(p[1], p[2]) for p in params]
15✔
53
            new_path = utils.add_url_params(request.path, params)
15✔
54
            content[0] = ' '.join([request.command, new_path, request.request_version])
15✔
55

56
        # split the request and optional response in the content.
57
        # The separator is two empty lines followed by a line starting with
58
        # 'HTTP/' or 'HTTP '
59
        request_content = StringList()
15✔
60
        request_content_no_fields = StringList()
15✔
61
        response_content = None
15✔
62
        emptylines_count = 0
15✔
63
        in_response = False
15✔
64
        is_field = r':({}) (.+): (.+)'.format('|'.join(AVAILABLE_FIELDS))
15✔
65
        for i, line in enumerate(content):
15✔
66
            source = content.source(i)
15✔
67
            if in_response:
15✔
68
                response_content.append(line, source)
15✔
69
            else:
70
                if emptylines_count >= 2 and (
15✔
71
                    line.startswith('HTTP/') or line.startswith('HTTP ')
72
                ):
73
                    in_response = True
15✔
74
                    response_content = StringList()
15✔
75
                    response_content.append(line, source)
15✔
76
                elif line == '':
15✔
77
                    emptylines_count += 1
15✔
78
                else:
79
                    request_content.extend(StringList([''] * emptylines_count, source))
15✔
80
                    request_content.append(line, source)
15✔
81

82
                    if not re.match(is_field, line):
15✔
83
                        request_content_no_fields.extend(
15✔
84
                            StringList([''] * emptylines_count, source)
85
                        )
86
                        request_content_no_fields.append(line, source)
15✔
87

88
                    emptylines_count = 0
15✔
89

90
        return (request_content, request_content_no_fields, response_content)
15✔
91

92
    def run(self):
15✔
93
        if self.content:
15✔
94
            processed = self.process_content(StringList(self.content))
15✔
95
            have_request = bool(processed[1])
15✔
96
            have_response = bool(processed[2])
15✔
97
        else:
98
            have_request = 'request' in self.options
15✔
99
            have_response = 'response' in self.options
15✔
100

101
        # Wrap and render main directive as 'http-example-http'
102
        klass = 'http-example-http'
15✔
103
        container = nodes.container('', classes=[klass])
15✔
104
        container.append(nodes.caption('', 'http'))
15✔
105
        block = HTTPExampleBlock(
15✔
106
            'http:example-block',
107
            ['http'],
108
            self.options,
109
            self.content,
110
            self.lineno,
111
            self.content_offset,
112
            self.block_text,
113
            self.state,
114
            self.state_machine,
115
        )
116
        container.extend(block.run())
15✔
117

118
        # Init result node list
119
        result = [container]
15✔
120

121
        # Append builder responses
122
        if have_request:
15✔
123
            for argument in self.arguments:
15✔
124
                name = argument
15✔
125
                # Setting plone JavaScript tab name
126
                name = 'JavaScript' if name == 'plone-javascript' else name
15✔
127

128
                options = self.options.copy()
15✔
129
                options.pop('name', None)
15✔
130
                options.pop('caption', None)
15✔
131

132
                block = HTTPExampleBlock(
15✔
133
                    'http:example-block',
134
                    [argument],
135
                    options,
136
                    self.content,
137
                    self.lineno,
138
                    self.content_offset,
139
                    self.block_text,
140
                    self.state,
141
                    self.state_machine,
142
                )
143

144
                # Wrap and render main directive as 'http-example-{name}'
145
                klass = 'http-example-{}'.format(name)
15✔
146
                container = nodes.container('', classes=[klass])
15✔
147
                container.append(nodes.caption('', name))
15✔
148
                container.extend(block.run())
15✔
149

150
                # Append to result nodes
151
                result.append(container)
15✔
152

153
        # Append optional response
154
        if have_response:
15✔
155
            options = self.options.copy()
15✔
156
            options.pop('name', None)
15✔
157
            options.pop('caption', None)
15✔
158

159
            block = HTTPExampleBlock(
15✔
160
                'http:example-block',
161
                ['http'],
162
                options,
163
                self.content,
164
                self.lineno,
165
                self.content_offset,
166
                self.block_text,
167
                self.state,
168
                self.state_machine,
169
            )
170

171
            # Wrap and render main directive as 'http-example-response'
172
            klass = 'http-example-response'
15✔
173
            container = nodes.container('', classes=[klass])
15✔
174
            container.append(nodes.caption('', 'response'))
15✔
175
            container.extend(block.run())
15✔
176

177
            # Append to result nodes
178
            result.append(container)
15✔
179

180
        # Final wrap
181
        container_node = nodes.container('', classes=['http-example'])
15✔
182
        container_node.extend(result)
15✔
183

184
        return [container_node]
15✔
185

186

187
class HTTPExampleBlock(CodeBlock):
15✔
188
    required_arguments = 1
15✔
189

190
    option_spec = utils.merge_dicts(
15✔
191
        CodeBlock.option_spec,
192
        {
193
            'request': directives.unchanged,
194
            'response': directives.unchanged,
195
        },
196
    )
197

198
    def read_http_file(self, path):
15✔
199
        cwd = os.path.dirname(self.state.document.current_source)
15✔
200
        request = utils.resolve_path(path, cwd)
15✔
201
        with open(request) as fp:
15✔
202
            return StringList(list(map(str.rstrip, fp.readlines())), request)
15✔
203

204
    def run(self):
15✔
205
        if self.arguments == ['http']:
15✔
206
            if 'request' in self.options:
15✔
207
                self.content = self.read_http_file(self.options['request'])
15✔
208
            else:
209
                self.content = HTTPExample.process_content(self.content)[1]
15✔
210
        elif self.arguments == ['response']:
15✔
211
            if 'response' in self.options:
9✔
212
                self.content = self.read_http_file(self.options['response'])
9✔
213
            else:
214
                self.content = HTTPExample.process_content(self.content)[2]
×
215

216
            self.arguments = ['http']
9✔
217
        else:
218
            if 'request' in self.options:
15✔
219
                request_content_no_fields = self.read_http_file(self.options['request'])
15✔
220
            else:
221
                request_content_no_fields = HTTPExample.process_content(self.content)[1]
15✔
222

223
            raw = ('\r\n'.join(request_content_no_fields)).encode('utf-8')
15✔
224

225
            config = self.env.config
15✔
226
            request = parsers.parse_request(raw, config.httpexample_scheme)
15✔
227
            name = choose_builders(self.arguments)[0]
15✔
228
            builder_, language = AVAILABLE_BUILDERS[name]
15✔
229
            self.arguments = [language]
15✔
230

231
            command = builder_(request)
15✔
232
            self.content = StringList([command], request_content_no_fields.source(0))
15✔
233

234
        return super(HTTPExampleBlock, self).run()
15✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc