Skip to content

Commit f1cb1b4

Browse files
committed
➕📝Add submit endpoint.
1 parent 6fad845 commit f1cb1b4

File tree

6 files changed

+202
-52
lines changed

6 files changed

+202
-52
lines changed

README.md

+85-8
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,23 @@ You can install jokeapi through [pip](https://pypi.org/project/pip/) by using `p
2020
# get_joke
2121

2222
The wrapper is structured in such a way that the end-user should only ever have to
23-
interact with one function. This function is `get_joke()`.
23+
interact with one function to get a joke. This function is `get_joke()`.
2424

2525
Please note that urllib3, the core dependency of this wrapper automatically abides by
2626
`Retry-After` headers, which means you may have to wait a long time for a joke if you
2727
have made a lot of requests recently
2828

2929
---
3030

31+
# submit_joke
32+
33+
The wrapper also provides simple access to the submit endpoint through the `submit_joke()`
34+
function.
35+
36+
Note that joke submissions are manually checked and you will be ratelimited.
37+
38+
---
39+
3140
## get_joke
3241

3342
### Example
@@ -54,7 +63,8 @@ A list of categories that the returned joke should fit in.
5463
Options are:
5564
`programming`,
5665
`miscellaneous`,
57-
`dark`
66+
`dark`,
67+
`pun`
5868

5969
If left blank it will default to use `Any`.
6070

@@ -205,12 +215,12 @@ Defaults to False.
205215

206216
---
207217

208-
## Returns
218+
### Returns
209219

210220
Depending on what format is chosen different things will be returned.
211221

212222

213-
### json
223+
#### json
214224

215225
A succesful API call will return:
216226

@@ -233,7 +243,7 @@ A succesful API call will return:
233243
```
234244

235245

236-
### xml
246+
#### xml
237247

238248
A succesful API call will return:
239249

@@ -256,7 +266,7 @@ A succesful API call will return:
256266
```
257267

258268

259-
### yaml
269+
#### yaml
260270

261271
A succesful API call will return:
262272

@@ -275,7 +285,7 @@ error: false
275285
```
276286
277287
278-
### txt
288+
#### txt
279289
280290
A succesful API call will return:
281291
@@ -287,7 +297,7 @@ He keeps dropping the database.
287297

288298
---
289299

290-
## Errors
300+
### Errors
291301

292302
The wrapper can raise multiple different errors depending on what you did wrong.
293303

@@ -296,6 +306,73 @@ If not, feel free to ask me through one of the channels provided below.
296306

297307
---
298308

309+
## submit_joke
310+
311+
### Example
312+
313+
```python
314+
from jokeapi import Jokes
315+
316+
j = Jokes()
317+
318+
j.submit_joke("Miscellaneous", "funny haha", {
319+
"nsfw": False,
320+
"religious": False,
321+
"political": False,
322+
"racist": False,
323+
"sexist": False
324+
}, lang="de")
325+
```
326+
327+
---
328+
329+
### Parameters
330+
331+
---
332+
333+
#### category
334+
335+
The category the joke is.
336+
Options are:
337+
`programming`,
338+
`miscellaneous`,
339+
`dark`,
340+
`pun`
341+
342+
Has no default value.
343+
344+
---
345+
346+
#### joke
347+
348+
The joke itself. Can either be a single string or a list/tuple, for the setup and
349+
delivery. Setup should be at index 0 in the tuple, delivery at 1.
350+
351+
Has no default value.
352+
353+
---
354+
355+
#### flags
356+
357+
The flags that the joke should have.
358+
Options are:
359+
`nsfw`,
360+
`religious`,
361+
`political`,
362+
`racist`,
363+
`sexist`
364+
365+
Has no default value.
366+
367+
#### lang
368+
369+
The language code for the language the joke it written in. E.g en for english,
370+
de for german.
371+
372+
Defaults to `en`
373+
374+
---
375+
299376
Developer contact:
300377

301378
![Discord](https://discord.com/assets/07dca80a102d4149e9736d4b162cff6f.ico)[**Discord**](https://discord.gg/mB989eP)
23 Bytes
Binary file not shown.
1.92 KB
Binary file not shown.

jokeapi/main.py

+102-26
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,31 @@
11
import urllib3
22
import urllib
3+
import urllib.request
34
import simplejson as json
45
import re
56

67

8+
class CategoryError(Exception):
9+
pass
10+
11+
12+
class BlacklistError(Exception):
13+
pass
14+
15+
16+
class ResponseTypeError(Exception):
17+
pass
18+
19+
20+
class JokeTypeError(Exception):
21+
pass
22+
23+
724
class Jokes:
825
def __init__(self):
926
self.http = urllib3.PoolManager()
10-
self.info = self.http.request('GET', "https://sv443.net/jokeapi/v2/info")
27+
self.info = self.http.request(
28+
'GET', "https://sv443.net/jokeapi/v2/info")
1129
self.info = data = json.loads(self.info.data.decode('utf-8'))["jokes"]
1230

1331
def build_request(
@@ -26,7 +44,7 @@ def build_request(
2644
if len(category):
2745
for c in category:
2846
if not c.title() in self.info["categories"]:
29-
raise ValueError(
47+
raise CategoryError(
3048
f'''Invalid category selected.
3149
You selected {c}.
3250
Available categories are:
@@ -39,31 +57,34 @@ def build_request(
3957
else:
4058
cats = "Any"
4159

42-
if len(blacklist) > 0:
43-
for b in blacklist:
44-
if b not in self.info["flags"]:
45-
raise ValueError(
46-
f'''
60+
if type(blacklist) in [list, tuple]:
61+
if len(blacklist) > 0:
62+
for b in blacklist:
63+
if b not in self.info["flags"]:
64+
raise BlacklistError(
65+
f'''
4766
4867
49-
You have blacklisted flags which are not available or you have not put the flags in a list.
50-
Available flags are:
51-
{"""
52-
""".join(self.info["flags"])}
53-
'''
54-
)
55-
return
56-
blacklistFlags = ",".join(blacklist)
68+
You have blacklisted flags which are not available.
69+
Available flags are:
70+
{"""
71+
""".join(self.info["flags"])}
72+
'''
73+
)
74+
return
75+
blacklistFlags = ",".join(blacklist)
76+
else:
77+
blacklistFlags = None
5778
else:
58-
blacklistFlags = None
79+
raise BlacklistError(f'''blacklist must be a list or tuple.''')
5980

6081
if response_format not in ["json", "xml", "yaml", "txt"]:
61-
raise Exception(
82+
raise ResponseTypeError(
6283
"Response format must be either json, xml, txt or yaml."
6384
)
6485
if type:
6586
if type not in ["single", "twopart"]:
66-
raise ValueError(
87+
raise JokeTypeError(
6788
'''Invalid joke type.
6889
Available options are "single" or "twopart".'''
6990
)
@@ -98,7 +119,6 @@ def build_request(
98119
if blacklistFlags:
99120
r += f"&blacklistFlags={blacklistFlags}"
100121

101-
102122
r += f"&type={type}"
103123

104124
if search_string:
@@ -107,7 +127,7 @@ def build_request(
107127
r += f"i&dRange={id_range[0]}-{id_range[1]}"
108128
if amount > 10:
109129
raise ValueError(
110-
f"amount parameter must be no greater than 10. you passed {amount}."
130+
f"amount parameter must be no greater than 10. you passed {amount}."
111131
)
112132
r += f"&amount={amount}"
113133

@@ -121,19 +141,21 @@ def send_request(self,
121141
return_headers,
122142
auth_token,
123143
user_agent
124-
):
144+
):
125145
returns = []
126146

127147
if auth_token:
128148
r = self.http.request('GET',
129149
request,
130150
headers={'Authorization': str(auth_token),
131151
'user-agent': str(user_agent),
132-
#'accept-encoding': 'gzip'
133-
}
152+
'accept-encoding': 'gzip'
153+
}
134154
)
135155
else:
136-
r = self.http.request('GET', request, headers={'user-agent': str(user_agent)})
156+
r = self.http.request('GET', request, headers={
157+
'user-agent': str(user_agent),
158+
'accept-encoding': 'gzip'})
137159

138160
data = r.data.decode('utf-8')
139161

@@ -156,7 +178,8 @@ def send_request(self,
156178
returns.append(headers)
157179

158180
if auth_token:
159-
returns.append({"Token-Valid": bool(int(re.split(r"Token-Valid", headers)[1][4]))})
181+
returns.append(
182+
{"Token-Valid": bool(int(re.split(r"Token-Valid", headers)[1][4]))})
160183

161184
if len(returns) > 1:
162185
return returns
@@ -180,5 +203,58 @@ def get_joke(
180203
category, blacklist, response_format, type, search_string, id_range, amount, lang
181204
)
182205

183-
response = self.send_request(r, response_format, return_headers, auth_token, user_agent)
206+
response = self.send_request(
207+
r, response_format, return_headers, auth_token, user_agent)
184208
return response
209+
210+
def submit_joke(self, category, joke, flags, lang="en"):
211+
request = {"formatVersion": 3}
212+
213+
if category not in self.info["categories"]:
214+
raise CategoryError(
215+
f'''Invalid category selected.
216+
You selected {category}.
217+
Available categories are:
218+
{"""
219+
""".join(self.info["categories"])}''')
220+
request["category"] = category
221+
222+
if type(joke) in [list, tuple]:
223+
if len(joke) > 1:
224+
request["type"] = "twopart"
225+
request["setup"] = joke[0]
226+
request["delivery"] = joke[1]
227+
else:
228+
request["type"] = "single"
229+
request["joke"] = joke[0]
230+
else:
231+
request["type"] = "single"
232+
request["joke"] = joke
233+
234+
for key in flags.keys():
235+
if key not in self.info["flags"]:
236+
raise BlacklistError(
237+
f'''
238+
You have blacklisted flags which are not available.
239+
Available flags are:
240+
{"""
241+
""".join(self.info["flags"])}
242+
''')
243+
request["flags"] = flags
244+
request["lang"] = lang
245+
246+
data = str(request).replace("'", '"')
247+
data = data.replace(": True", ": true").replace(": False", ": false")
248+
data = data.encode('ascii')
249+
url = "https://sv443.net/jokeapi/v2/submit"
250+
251+
try:
252+
response = urllib.request.urlopen(url, data=data)
253+
data = response.getcode()
254+
255+
return data
256+
except urllib.error.HTTPError as e:
257+
body = e.read().decode() # Read the body of the error response
258+
259+
_json = json.loads(body)
260+
return _json

setup.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,20 @@
33
with open("README.md", "r") as fh:
44
long_description = fh.read()
55

6+
version = "0.2.7"
7+
68
setuptools.setup(
79
name="jokeapi",
810
packages=["jokeapi"],
9-
version="0.2.6",
11+
version=version,
1012
license="GNU General Public License v3 (GPLv3)",
1113
description="An API Wrapper for Sv443's JokeAPI",
1214
long_description=long_description,
1315
long_description_content_type="text/markdown",
1416
author="thenamesweretakenalready",
1517
author_email="[email protected]",
1618
url="""https://github.com/thenamesweretakenalready/Sv443s-JokeAPI-Python-Wrapper""",
17-
download_url="https://github.com/thenamesweretakenalready/Sv443s-JokeAPI-Python-Wrapper/archive/v0.2.6.tar.gz",
19+
download_url=f"https://github.com/thenamesweretakenalready/Sv443s-JokeAPI-Python-Wrapper/archive/v{version}.tar.gz",
1820
keywords=["api wrapper", "wrapper", "api", "jokes", "python", "joke api"],
1921
install_requires=[
2022
"urllib3==1.25.8",

0 commit comments

Comments
 (0)