Skip to content

Commit dfea92e

Browse files
committed
initial commit
0 parents  commit dfea92e

10 files changed

+1318
-0
lines changed

.gitignore

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# These are some examples of commonly ignored file patterns.
2+
# You should customize this list as applicable to your project.
3+
# Learn more about .gitignore:
4+
# https://www.atlassian.com/git/tutorials/saving-changes/gitignore
5+
6+
# Node artifact files
7+
node_modules/
8+
dist/
9+
10+
# Compiled Java class files
11+
*.class
12+
13+
# Compiled Python bytecode
14+
*.py[cod]
15+
16+
# Log files
17+
*.log
18+
19+
# Package files
20+
*.jar
21+
22+
# Maven
23+
target/
24+
dist/
25+
26+
# JetBrains IDE
27+
.idea/
28+
29+
# Unit test reports
30+
TEST*.xml
31+
32+
# Generated by MacOS
33+
.DS_Store
34+
35+
# Generated by Windows
36+
Thumbs.db
37+
38+
# Applications
39+
*.app
40+
*.exe
41+
*.war
42+
43+
# Large media files
44+
*.mp4
45+
*.tiff
46+
*.avi
47+
*.flv
48+
*.mov
49+
*.wmv
50+

README.md

+109
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
# Request Curl
2+
3+
User-friendly wrapper for pycurl
4+
5+
## Installation
6+
Use the package manager
7+
[pip](https://pip.pypa.io/en/stable/)
8+
to install request_curl.
9+
10+
```
11+
pip install request_curl
12+
```
13+
14+
## HTTP2
15+
HTTP2 is disabled by default.
16+
17+
```python
18+
import request_curl
19+
s = request_curl.Session(http2=True)
20+
r = s.get("https://www.example.com")
21+
```
22+
23+
## Proxy Support
24+
Proxy has to be formatted as a string.
25+
26+
```python
27+
import request_curl
28+
s = request_curl.Session()
29+
r = s.get("https://www.example.com", proxies="ip:port:user:password")
30+
```
31+
32+
## Content Decoding
33+
```python
34+
import request_curl
35+
s = request_curl.Session(accept_encoding="br, gzip, deflate")
36+
r = s.get("https://www.example.com", debug=True)
37+
```
38+
39+
## Response Object
40+
41+
The response object behaves
42+
similar to the one of the requests library.
43+
44+
```python
45+
import request_curl
46+
s = request_curl.Session()
47+
r = s.get("https://www.example.com")
48+
49+
print(r)
50+
print(r.status_code)
51+
print(r.content)
52+
print(r.text)
53+
print(r.json)
54+
print(r.url)
55+
print(r.history)
56+
```
57+
58+
## Cipher Suites
59+
You can specify custom cipher suites as an array.
60+
61+
```python
62+
import request_curl
63+
64+
cipher_suite = [
65+
"AES128-SHA256",
66+
"AES256-SHA256",
67+
"AES128-GCM-SHA256",
68+
"AES256-GCM-SHA384"
69+
]
70+
s = request_curl.Session(cipher_suite=cipher_suite)
71+
r = s.get("https://www.example.com")
72+
```
73+
74+
## Debug Request
75+
If debug is set to True the raw input
76+
and output headers will bre printed out.
77+
78+
```python
79+
import request_curl
80+
s = request_curl.Session()
81+
r = s.get("https://www.example.com", debug=True)
82+
```
83+
84+
## Custom Header
85+
You can specify custom a customer header
86+
as a dictionary.
87+
88+
```python
89+
import request_curl
90+
s = request_curl.Session()
91+
headers = {
92+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36"
93+
}
94+
r = s.get("https://www.example.com", headers=headers)
95+
```
96+
97+
## Install with Curl-Impersonate
98+
- https://github.com/lwthiker/curl-impersonate/blob/main/INSTALL.md
99+
- sudo apt install build-essential pkg-config cmake ninja-build curl autoconf automake libtool
100+
- ``sudo apt install -y libbrotli-dev golang build-essential libnghttp2-dev cmake libunwind-dev libssl-dev git python3-dev``
101+
- git clone https://github.com/pycurl/pycurl.git
102+
- sudo python3 setup.py install --curl-config=/usr/local/bin/curl-impersonate-chrome-config
103+
104+
```python
105+
import pycurl
106+
pycurl.version_info()
107+
# (9, '7.84.0', 480256, 'x86_64-pc-linux-gnu', 1370063517, 'BoringSSL', 0, '1.2.11', ('dict', 'file', 'ftp', 'ftps', 'gopher', 'gophers', 'http', 'https', 'imap', 'imaps', 'mqtt', 'pop3', 'pop3s', 'rtsp', 'smb', 'smbs', 'smtp', 'smtps', 'telnet', 'tftp'), None, 0, None)
108+
quit()
109+
```

poetry.lock

+392
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
[tool.poetry]
2+
name = "request_curl"
3+
version = "0.0.1"
4+
description = ""
5+
authors = ["Notifysolutions <Ennis Blank, Mauritz Uphoff>"]
6+
7+
[tool.poetry.dependencies]
8+
python = "^3.10"
9+
requests = "^2.28.1"
10+
Brotli = "^1.0.9"
11+
pycurl = "^7.45.2"
12+
13+
[tool.poetry.dev-dependencies]
14+
pytest = "^7.1.3"
15+
16+
[build-system]
17+
requires = ["poetry-core>=1.0.0"]
18+
build-backend = "poetry.core.masonry.api"

request_curl/__init__.py

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# GET/OPTIONS/POST/PUT/PATCH/DELETE/HEAD
2+
from .api import get, options, post, put, patch, delete, head, request
3+
from .sessions import Session
4+
5+
version = "0.0.1"

request_curl/api.py

+152
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
"""
2+
:copyright: (c) 2022 by Mauritz Uphoff.
3+
"""
4+
from .sessions import Session
5+
6+
7+
def request(method, url, **kwargs):
8+
"""Constructs and sends a :class:`Request <Request>`.
9+
:param method: method for the new :class:`Request` object:
10+
``GET``, ``OPTIONS``, ``HEAD``, ``POST``, ``PUT``, ``PATCH``, or ``DELETE``.
11+
:param url: URL for the new :class:`Request` object.
12+
:param params: (optional) Dictionary, list of tuples or bytes to send
13+
in the query string for the :class:`Request`.
14+
:param data: (optional) Dictionary, list of tuples, bytes, or file-like
15+
object to send in the body of the :class:`Request`.
16+
:param json: (optional) A JSON serializable Python object
17+
to send in the body of the :class:`Request`.
18+
:param headers: (optional) Dictionary of HTTP Headers to send with the :class:`Request`.
19+
:param cookies: (optional) Dict or CookieJar object to send with the :class:`Request`.
20+
:param files: (optional) Dictionary of ``'name': file-like-objects`` (or ``{'name': file-tuple}``) for multipart encoding upload.
21+
``file-tuple`` can be a 2-tuple ``('filename', fileobj)``, 3-tuple ``('filename', fileobj, 'content_type')``
22+
or a 4-tuple ``('filename', fileobj, 'content_type', custom_headers)``, where ``'content-type'`` is a string
23+
defining the content type of the given file and ``custom_headers`` a dict-like object containing additional headers
24+
to add for the file.
25+
:param auth: (optional) Auth tuple to enable Basic/Digest/Custom HTTP Auth.
26+
:param timeout: (optional) How many seconds to wait for the server to send data
27+
before giving up, as a float, or a :ref:`(connect timeout, read
28+
timeout) <timeouts>` tuple.
29+
:type timeout: float or tuple
30+
:param allow_redirects: (optional) Boolean. Enable/disable
31+
GET/OPTIONS/POST/PUT/PATCH/DELETE/HEAD redirection. Defaults to ``True``.
32+
:type allow_redirects: bool
33+
:param proxies: (optional) String to the URL of the proxy.
34+
:param verify: (optional) Either a boolean, in which case it controls whether we verify
35+
the server's TLS certificate, or a string, in which case it must be a path
36+
to a CA bundle to use. Defaults to ``True``.
37+
:return: :class:`Response <Response>` object
38+
:rtype: requests.Response
39+
40+
Usage::
41+
42+
>>> import request_curl
43+
>>> req = request_curl.request('GET', 'https://httpbin.org/get')
44+
>>> req
45+
<Response [200]>
46+
"""
47+
48+
# By using the 'with' statement we are sure the session is closed, thus we
49+
# avoid leaving sockets open which can trigger a ResourceWarning in some
50+
# cases, and look like a memory leak in others.
51+
with Session() as session:
52+
return session.request(method, url, **kwargs)
53+
54+
55+
def get(url, params=None, **kwargs):
56+
r"""Sends a GET request.
57+
58+
:param url: URL for the new :class:`Request` object.
59+
:param params: (optional) Dictionary, list of tuples or bytes to send
60+
in the query string for the :class:`Request`.
61+
:param \*\*kwargs: Optional arguments that ``request`` takes.
62+
:return: :class:`Response <Response>` object
63+
:rtype: requests.Response
64+
"""
65+
66+
return request('get', url, params=params, **kwargs)
67+
68+
69+
def options(url, **kwargs):
70+
r"""Sends an OPTIONS request.
71+
72+
:param url: URL for the new :class:`Request` object.
73+
:param \*\*kwargs: Optional arguments that ``request`` takes.
74+
:return: :class:`Response <Response>` object
75+
:rtype: requests.Response
76+
"""
77+
78+
return request('options', url, **kwargs)
79+
80+
81+
def head(url, **kwargs):
82+
r"""Sends a HEAD request.
83+
84+
:param url: URL for the new :class:`Request` object.
85+
:param \*\*kwargs: Optional arguments that ``request`` takes. If
86+
`allow_redirects` is not provided, it will be set to `False` (as
87+
opposed to the default :meth:`request` behavior).
88+
:return: :class:`Response <Response>` object
89+
:rtype: requests.Response
90+
"""
91+
92+
kwargs.setdefault('allow_redirects', False)
93+
return request('head', url, **kwargs)
94+
95+
96+
def post(url, data=None, json=None, **kwargs):
97+
r"""Sends a POST request.
98+
99+
:param url: URL for the new :class:`Request` object.
100+
:param data: (optional) Dictionary, list of tuples, bytes, or file-like
101+
object to send in the body of the :class:`Request`.
102+
:param json: (optional) json data to send in the body of the :class:`Request`.
103+
:param \*\*kwargs: Optional arguments that ``request`` takes.
104+
:return: :class:`Response <Response>` object
105+
:rtype: requests.Response
106+
"""
107+
108+
return request('post', url, data=data, json=json, **kwargs)
109+
110+
111+
def put(url, data=None, **kwargs):
112+
r"""Sends a PUT request.
113+
114+
:param url: URL for the new :class:`Request` object.
115+
:param data: (optional) Dictionary, list of tuples, bytes, or file-like
116+
object to send in the body of the :class:`Request`.
117+
:param json: (optional) json data to send in the body of the :class:`Request`.
118+
:param \*\*kwargs: Optional arguments that ``request`` takes.
119+
:return: :class:`Response <Response>` object
120+
:rtype: requests.Response
121+
"""
122+
123+
return request('put', url, data=data, **kwargs)
124+
125+
126+
def patch(url, data=None, **kwargs):
127+
r"""Sends a PATCH request.
128+
129+
:param url: URL for the new :class:`Request` object.
130+
:param data: (optional) Dictionary, list of tuples, bytes, or file-like
131+
object to send in the body of the :class:`Request`.
132+
:param json: (optional) json data to send in the body of the :class:`Request`.
133+
:param \*\*kwargs: Optional arguments that ``request`` takes.
134+
:return: :class:`Response <Response>` object
135+
:rtype: requests.Response
136+
"""
137+
138+
return request('patch', url, data=data, **kwargs)
139+
140+
141+
def delete(url, **kwargs):
142+
r"""Sends a DELETE request.
143+
144+
:param url: URL for the new :class:`Request` object.
145+
:param \*\*kwargs: Optional arguments that ``request`` takes.
146+
:return: :class:`Response <Response>` object
147+
:rtype: requests.Response
148+
"""
149+
150+
return request('delete', url, **kwargs)
151+
152+

0 commit comments

Comments
 (0)