def test_exchange_refresh_token(self): def response_callback(payload): self.assertEqual(payload["refresh_token"][0], "myrefreshtoken") self.assertEqual(payload["client_id"][0], "myclientid") self.assertEqual(payload["client_secret"][0], "myclientsecret") self.assertEqual(payload["grant_type"][0], "refresh_token") data = { "token_type": "Bearer", "access_token": "myaccesstoken2", "expires_at": 4575744000000, "refresh_token": "myrefreshtoken2", "scope": ["basicProfile"], } return (201, data) self._mock_endpoint("POST", "/v1/tokens", response_callback, is_json=False) client = Client(application_id="myclientid", application_secret="myclientsecret") # TODO(kyle) Remove after Ceasar's refactoring resp = client.exchange_refresh_token("myrefreshtoken") self.assertEqual(resp["access_token"], "myaccesstoken2") self.assertEqual(resp["refresh_token"], "myrefreshtoken2") self.assertEqual(resp["scope"], ["basicProfile"])
def _execute(self, options, args): """Publish to Medium.""" if not os.path.exists('medium.json'): LOGGER.error( 'Please put your credentials in medium.json as described in the README.' ) return False with open('medium.json') as inf: creds = json.load(inf) client = Client() client.access_token = creds['TOKEN'] user = client.get_current_user() self.site.scan_posts() for post in self.site.timeline: if post.meta('medium'): m_post = client.create_post( user_id=user["id"], title=post.title(), content=post.text(), content_format="html", publish_status="public", canonical_url=post.permalink(absolute=True), tags=post.tags) print('Published %s to %s' % (post.meta('slug'), m_post['url']))
def setClient(self, channel): logging.info(" Connecting Medium") logging.info(f" Connecting Medium {channel}") self.service = 'Medium' client = None userRaw = None user = None try: config = configparser.ConfigParser() config.read(CONFIGDIR + '/.rssMedium') application_id = config.get("appKeys", "ClientID") application_secret = config.get("appKeys", "ClientSecret") try: client = Client(application_id=application_id, application_secret=application_secret) try: client.access_token = config.get(channel, "access_token") except: client.access_token = config.get("appKeys", "access_token") # client.access_token = config.get("appKeys","access_token") # Get profile details of the user identified by the access # token. userRaw = client.get_current_user() user = userRaw['username'] except: logging.warning("Medium authentication failed!") logging.warning("Unexpected error:", sys.exc_info()) except: logging.warning("Account not configured") self.client = client self.user = user self.userRaw = userRaw
class TestIsaac(unittest.TestCase): def setUp(self): self.client = Client(access_token="isaac-token") @responses.activate def test_create_post_fails(self): """Tests whether MediumError exception occurs if publish_status is not in the payload""" def response_callback(payload): data = { "license": "all-rights-reserved", "title": "Starships", "url": "https://medium.com/@nicki/55050649c95", "tags": ["stars", "ships", "pop"], "authorId": "5303d74c64f66366f00cb9b2a94f3251bf5", "publishStatus": "draft", "id": "55050649c95", } if "publish_status" in payload: return 200, data return 400, {"error": ["Bad Request"]} self._mock_endpoint( "POST", "/v1/users/5303d74c64f66366f00cb9b2a94f3251bf5/posts", response_callback) with self.assertRaises(MediumError) as context: self.client.create_post("5303d74c64f66366f00cb9b2a94f3251bf5", "Starships", "<p>Are meant to flyyyy</p>", "html", tags=["stars", "ships", "pop"]) self.assertEqual('API request failed', str(context.exception)) def _mock_endpoint(self, method, path, callback, is_json=True): def wrapped_callback(req): if is_json: self.assertEqual(req.headers["Authorization"], "Bearer isaac-token") if req.body is not None: body = json.loads(req.body) if is_json else parse_qs(req.body) else: body = None status, data = callback(body) return status, {}, json.dumps(data) response_method = responses.GET if method == "GET" else responses.POST url = "https://api.medium.com" + path content_type = ("application/json" if is_json else "application/x-www-form-urlencoded") responses.add_callback(response_method, url, content_type=content_type, callback=wrapped_callback)
def postToMedium(heading,body): client = Client(application_id = ENV["APP_ID"],application_secret = ENV["APP_SECRET"]) client.access_token = ENV["ACCESS_TOKEN"] user = client.get_current_user() post = client.create_post(user_id = user["id"], title = heading, content = body, content_format = "markdown", publish_status = "draft") print("New!! post at ",post["url"])
def push_to_medium(self): """Prepare final content, upload post to Medium""" self.title = self.meta.get('title', config.DEFAULT_TITLE) if self.include_attribution: self.add_attribution() self.content = ''.join(self.final_lines) client = Client(access_token=secrets.MEDIUM_TOKEN) me = client.get_current_user() self.post = client.create_post(user_id=me['id'], title=self.title, \ content=self.content, content_format="markdown", \ publish_status=config.PUBLISH_STATUS) print(self.post)
def resultDisplay(): #intialisation client = Client(application_id=medium_app_id, application_secret=medium_app_secret) #post="Post" #client._request(post,"https://86acd90c.ngrok.io/resultDisplay/") # Build the URL where you can send the user to obtain an authorization code. auth_url = client.get_authorization_url( "secretstate", "{}/resultDisplay/callback/medium".format(ngrok_link), ["basicProfile", "publishPost", "listPublications"]) # auth = client.exchange_authorization_code(print(auth_url),"https://b351e15d.ngrok.io/resultDisplay/callback/medium") return redirect(auth_url, code=302)
def connectMedium(): config = configparser.ConfigParser() config.read([os.path.expanduser('~/.rssMedium')]) client = Client(application_id=config.get("appKeys", "ClientID"), application_secret=config.get("appKeys", "ClientSecret")) try: client.access_token = config.get("appKeys", "access_token") # Get profile details of the user identified by the access token. user = client.get_current_user() except: print("Medium authentication failed!\n") print("Unexpected error:", sys.exc_info()[0]) return (client, user)
def medium_callback(): if request.args.get('code'): client = Client( application_id="888a966258eb", application_secret="00769027e3d5b60bef015e4924a2bc3022218de9") auth_code = request.args.get('code') auth = client.exchange_authorization_code( auth_code, "http://0094f685.ngrok.io/api/callback/medium") client.access_token = auth["access_token"] user = client.get_current_user() user_dir = 'users/' + user["username"] if not os.path.exists(user_dir): os.makedirs(user_dir) with open(user_dir + '/token.json', 'w+') as f: json.dump(auth, f) f.close() with open(user_dir + '/user.json', 'w+') as f: json.dump(user, f) f.close() with open('users.txt', 'a+') as f: f.write('{}\n'.format(user["username"])) f.close()
def _execute(self, options, args): """Publish to Medium.""" if not os.path.exists('medium.json'): LOGGER.error( 'Please put your credentials in medium.json as described in the README.') return False with open('medium.json') as inf: creds = json.load(inf) client = Client() client.access_token = creds['TOKEN'] user = client.get_current_user() self.site.scan_posts() for post in self.site.timeline: if post.meta('medium'): m_post = client.create_post( user_id=user["id"], title=post.title(), content=post.text(), content_format="html", publish_status="public", canonical_url=post.permalink(absolute=True), tags=post.tags ) print('Published %s to %s' % (post.meta('slug'), m_post['url']))
def post_content(medium_content, digest_config=None): "post the Medium content to Medium" medium_client = Client( application_id=digest_config.get("medium_application_client_id"), application_secret=digest_config.get( "medium_application_client_secret"), ) medium_client.access_token = digest_config.get("medium_access_token") medium_user = medium_client.get_current_user() # Set some optional post values publish_status = "draft" medium_license = digest_config.get("medium_license", None) # Create a draft post post = medium_client.create_post( user_id=medium_user["id"], title=utils.formatter_string(medium_content, "title"), content=utils.formatter_string(medium_content, "content"), content_format=utils.formatter_string(medium_content, "contentFormat"), tags=utils.formatter_string(medium_content, "tags"), publish_status=publish_status, license=medium_license, ) return post
def get_current_publications(user_id, acess_token): url = "https://api.medium.com/v1/users/{}/publications".format( user_id) #?type=json token = acess_token get_pub = Client(application_id=medium_app_id, application_secret=medium_app_secret) return requests.request("GET", url, headers={ "Accept": "application/json", "Accept-Charset": "utf-8", "Authorization": "Bearer %s" % token, })
def _execute(self, options, args): """Publish to Medium.""" if not os.path.exists("medium.json"): LOGGER.error( "Please put your credentials in medium.json as described in the README." ) return False with open("medium.json") as inf: creds = json.load(inf) client = Client() client.access_token = creds["TOKEN"] user = client.get_current_user() self.site.scan_posts() feed = client.list_articles(user["username"]) posts = self.site.timeline medium_titles = {item["title"] for item in feed} to_post = [ post for post in posts if post.title() not in medium_titles and post.meta("medium") ] if len(to_post) == 0: print("Nothing new to post...") for post in to_post: with open(post.source_path, "r") as file: data = file.read() pattern = "(?m)^# .*\n$" title = "" match = re.search(pattern, data) if not match: title = f"# {post.title()}\n" content = (title + "*Original article : " + post.permalink(absolute=True) + "*\n" + data) else: content = (data[:match.end()] + "\n*Original article : " + post.permalink(absolute=True) + "*\n" + data[match.end():]) m_post = client.create_post( user_id=user["id"], title=post.title(), content=content, content_format="markdown", publish_status="public", canonical_url=post.permalink(absolute=True), tags=post.tags, ) print("Published %s to %s" % (post.meta("slug"), m_post["url"]))
def publish(request): if request.method=="POST": title=request.POST["title"] imgloc=request.POST["img_loc"] content=request.POST["message"] client=Client(application_id="bd2220b27e6a",application_secret="5ea5ccec18e6b7d12466900d47417fdcc52f352f") client.access_token="2a0432ffe8985834d0f939991291b6d589eef0684b425e8fce1c964a7e0be1263" user=client.get_current_user() imgup=client.upload_image(file_path=os.path.join('D:\\IV\\One plus\\Photos',imgloc),content_type="image/jpeg") url=imgup['url'] content="<img src="+url+"><p>"+content+ "</p>" post=client.create_post(user_id=user["id"], title=title,content=content,content_format="html") return render(request,'blank.html',post) else: return render(request,'index.html')
def _execute(self, options, args): """Publish to Medium.""" if not os.path.exists("medium.json"): LOGGER.error( "Please put your credentials in medium.json as described in the README." ) return False with open("medium.json") as inf: creds = json.load(inf) client = Client() client.access_token = creds["TOKEN"] user = client.get_current_user() self.site.scan_posts() feed = client.list_articles(user["username"]) posts = self.site.timeline medium_titles = {item["title"] for item in feed} to_post = [ post for post in posts if post.title() not in medium_titles and post.meta("medium") ] if len(to_post) == 0: print("Nothing new to post...") for post in to_post: tree = html.fromstring(post.text()) toc = tree.xpath('//nav[@id="TOC"]') if len(toc) != 0: toc[0].getparent().remove(toc[0]) if len(tree.xpath("//h1")) == 0: content = "<h1>" + post.title() + "</h1>\n" body = tree.xpath("//div")[0] body.insert(0, etree.XML(content)) m_post = client.create_post( user_id=user["id"], title=post.title(), content=etree.tostring(tree, encoding=str), content_format="html", publish_status="public", canonical_url=post.permalink(absolute=True), tags=post.tags, ) print("Published %s to %s" % (post.meta("slug"), m_post["url"]))
def test_exchange_authorization_code(self): def response_callback(payload): self.assertEqual(payload["code"][0], "mycode") self.assertEqual(payload["client_id"][0], "myclientid") self.assertEqual(payload["client_secret"][0], "myclientsecret") self.assertEqual(payload["grant_type"][0], "authorization_code") self.assertEqual(payload["redirect_uri"][0], "http://example.com/cb") data = { "token_type": "Bearer", "access_token": "myaccesstoken", "expires_at": 4575744000000, "refresh_token": "myrefreshtoken", "scope": ["basicProfile"], } return (201, data) self._mock_endpoint("POST", "/v1/tokens", response_callback, is_json=False) client = Client(application_id="myclientid", application_secret="myclientsecret")
from medium import Client client=Client(application_id="bd2220b27e6a",application_secret="5ea5ccec18e6b7d12466900d47417fdcc52f352f") client.access_token ="2a0432ffe8985834d0f939991291b6d589eef0684b425e8fce1c964a7e0be1263" user=client.get_current_user()
def setUp(self): self.client = Client(access_token="myaccesstoken")
post_id = item_post["postId"] print("----extremeAdaptiveSection!!!!") print(post_url(post_id)) except requests.exceptions.ConnectionError: print("Connection refused") if __name__ == '__main__': do_auth = True get_home_articles() if do_auth: # Go to http://medium.com/me/applications to get your application_id and application_secret. client = Client(application_id=MEDIUM_CLIENT_ID, application_secret=MEDIUM_CLIENT_SECRET) # Build the URL where you can send the user to obtain an authorization code. auth_url = client.get_authorization_url( "secretstate", callback_url, ["basicProfile", "publishPost", "listPublications"]) # (Send the user to the authorization URL to obtain an authorization code.) print(auth_url) webbrowser.open(auth_url, new=2) print( "Authorization code (at the end of the url that was just opened):") authorization_code = sys.stdin.readline().strip()
def setUp(self): self.client = Client(access_token="isaac-token")
import urllib import requests from medclient import exchangeAuth from medium import Client import tomd # hard coded variables for right now config = configparser.ConfigParser() config.read('config.ini') client_id = config['DEFAULT']['CLIENT_ID'] # medium api client id client_secret = config['DEFAULT']['CLIENT_SECRET'] # medium api client secret callback_url = 'http://127.0.0.1:5000/callback/medium' user_name = 'kauri_io' client = Client(application_id=client_id, application_secret=client_secret) app = Flask(__name__) @app.route('/callback/frontend', methods=['GET', 'POST']) def medium_callback(): if request.args.get('state') and request.args.get('code'): state = request.args.get('state') code = request.args.get('code') data = { "code": code, "client_id": client_id, "client_secret": client_secret, "grant_type": "authorization_code", "redirect_uri": redirect_url,
class TestClient(unittest.TestCase): def setUp(self): self.client = Client(access_token="myaccesstoken") @responses.activate def test_exchange_authorization_code(self): def response_callback(payload): self.assertEqual(payload["code"][0], "mycode") self.assertEqual(payload["client_id"][0], "myclientid") self.assertEqual(payload["client_secret"][0], "myclientsecret") self.assertEqual(payload["grant_type"][0], "authorization_code") self.assertEqual(payload["redirect_uri"][0], "http://example.com/cb") data = { "token_type": "Bearer", "access_token": "myaccesstoken", "expires_at": 4575744000000, "refresh_token": "myrefreshtoken", "scope": ["basicProfile"], } return (201, data) self._mock_endpoint("POST", "/v1/tokens", response_callback, is_json=False) client = Client(application_id="myclientid", application_secret="myclientsecret") # TODO(kyle) Remove after Ceasar's refactoring resp = client.exchange_authorization_code("mycode", "http://example.com/cb") self.assertEqual(resp["access_token"], "myaccesstoken") self.assertEqual(resp["refresh_token"], "myrefreshtoken") self.assertEqual(resp["scope"], ["basicProfile"]) # TODO(kyle) Uncomment after Ceasar's refactoring # client.exchange_authorization_code("mycode", "http://example.com/cb") # self.assertEqual(client.access_token, "myaccesstoken") # self.assertEqual(client.refresh_token, "myrefreshtoken") @responses.activate def test_exchange_refresh_token(self): def response_callback(payload): self.assertEqual(payload["refresh_token"][0], "myrefreshtoken") self.assertEqual(payload["client_id"][0], "myclientid") self.assertEqual(payload["client_secret"][0], "myclientsecret") self.assertEqual(payload["grant_type"][0], "refresh_token") data = { "token_type": "Bearer", "access_token": "myaccesstoken2", "expires_at": 4575744000000, "refresh_token": "myrefreshtoken2", "scope": ["basicProfile"], } return (201, data) self._mock_endpoint("POST", "/v1/tokens", response_callback, is_json=False) client = Client(application_id="myclientid", application_secret="myclientsecret") # TODO(kyle) Remove after Ceasar's refactoring resp = client.exchange_refresh_token("myrefreshtoken") self.assertEqual(resp["access_token"], "myaccesstoken2") self.assertEqual(resp["refresh_token"], "myrefreshtoken2") self.assertEqual(resp["scope"], ["basicProfile"]) # TODO(kyle) Uncomment after Ceasar's refactoring # client.exchange_refresh_token("myrefreshtoken") # self.assertEqual(client.access_token, "myaccesstoken2") # self.assertEqual(client.refresh_token, "myrefreshtoken2") @responses.activate def test_get_current_user(self): def response_callback(payload): data = { "username": "******", "url": "https://medium.com/@nicki", "imageUrl": "https://images.medium.com/0*fkfQiTzT7TlUGGyI.png", "id": "5303d74c64f66366f00cb9b2a94f3251bf5", "name": "Nicki Minaj", } return 200, data self._mock_endpoint("GET", "/v1/me", response_callback) resp = self.client.get_current_user() self.assertEqual(resp, { "username": "******", "url": "https://medium.com/@nicki", "imageUrl": "https://images.medium.com/0*fkfQiTzT7TlUGGyI.png", "id": "5303d74c64f66366f00cb9b2a94f3251bf5", "name": "Nicki Minaj", }) @responses.activate def test_create_post(self): def response_callback(payload): self.assertEqual(payload, { "title": "Starships", "content": "<p>Are meant to flyyyy</p>", "contentFormat": "html", "tags": ["stars", "ships", "pop"], "publishStatus": "draft", }) data = { "license": "all-rights-reserved", "title": "Starships", "url": "https://medium.com/@nicki/55050649c95", "tags": ["stars", "ships", "pop"], "authorId": "5303d74c64f66366f00cb9b2a94f3251bf5", "publishStatus": "draft", "id": "55050649c95", } return 200, data self._mock_endpoint( "POST", "/v1/users/5303d74c64f66366f00cb9b2a94f3251bf5/posts", response_callback ) resp = self.client.create_post( "5303d74c64f66366f00cb9b2a94f3251bf5", "Starships", "<p>Are meant to flyyyy</p>", "html", tags=["stars", "ships", "pop"], publish_status="draft" ) self.assertEqual(resp, { "license": "all-rights-reserved", "title": "Starships", "url": "https://medium.com/@nicki/55050649c95", "tags": ["stars", "ships", "pop"], "authorId": "5303d74c64f66366f00cb9b2a94f3251bf5", "publishStatus": "draft", "id": "55050649c95", }) @responses.activate def test_upload_image(self): def response_callback(req): self.assertEqual(req.headers["Authorization"], "Bearer myaccesstoken") self.assertIn(b"Content-Type: image/png", req.body) return 200, {}, json.dumps({ "url": "https://cdn-images-1.medium.com/0*dlkfjalksdjfl.jpg", "md5": "d87e1628ca597d386e8b3e25de3a18bc", }) responses.add_callback(responses.POST, "https://api.medium.com/v1/images", content_type="application/json", callback=response_callback) resp = self.client.upload_image("./tests/test.png", "image/png") self.assertEqual(resp, { "url": "https://cdn-images-1.medium.com/0*dlkfjalksdjfl.jpg", "md5": "d87e1628ca597d386e8b3e25de3a18bc", }) def _mock_endpoint(self, method, path, callback, is_json=True): def wrapped_callback(req): if is_json: self.assertEqual(req.headers["Authorization"], "Bearer myaccesstoken") if req.body is not None: body = json.loads(req.body) if is_json else parse_qs(req.body) else: body = None status, data = callback(body) return (status, {}, json.dumps(data)) response_method = responses.GET if method == "GET" else responses.POST url = "https://api.medium.com" + path content_type = ("application/json" if is_json else "application/x-www-form-urlencoded") responses.add_callback(response_method, url, content_type=content_type, callback=wrapped_callback)
def call_back(): global refresh_button_click global total_posts global count_length global user_profile global user_image global user_type global pub_name global desrip_pub global image_pub global url_pub global rss_link if (refresh_button_click == True): #authentication process to get the acess token # Exchange the authorization code for an access token. client = Client(application_id=medium_app_id, application_secret=medium_app_secret) #get_pub = Client(application_id="45ec1ddf13cb", application_secret="b42623c0f2ee207a6872a76c0bc7c2eb88411a77") secret = request.args.get("code") auth = client.exchange_authorization_code( secret, "{}/resultDisplay/callback/medium".format(ngrok_link)) client.access_token = auth["access_token"] # Get profile details of the user identified by the access token. user = client.get_current_user() user_profile = user["username"] user_image = user["imageUrl"] user_id = user["id"] user_type = type(user) token = auth["access_token"] publications = get_current_publications(user_id, token) json_data_type = json.loads(publications.text) #publications.json() data_list = json_data_type["data"] #capture the data in the database.... database.insert_data(user_profile, user, data_list, datetime.now()) # To determined the length of the publication.. count_length = len(data_list) #testing #rss_links1=rss_feed[1].get("link") get_publications_data(data_list) ''' for dict_item in data_list: for key,value in dict_item.items(): if key=="id": pass else: if key=="name": pub_name.append(value) if key=="description": desrip_pub.append(value) if key=="imageUrl": image_pub.append(value) if key=="url": url_pub.append(value) ''' #person_data["name"] #get the user feeder data name = str(user["username"]) rss_feed = get_medium(name) #store relevant data from the rss_feed to the rss_list get_medium_rss_data(rss_feed) #get the total posts of the user total_posts = len(rss_feed) #set refresh button click to false. refresh_button_click = False return render_template('callback.html', total_posts=total_posts, count_length=count_length, user_profile=user_profile, user_image=user_image, user_type=user_type, pub_name=pub_name, desrip_pub=desrip_pub, image_pub=image_pub, url_pub=url_pub, rss_links=rss_links, rss_tags=rss_tags, rss_titles=rss_titles) else: if (database.is_greater_than_cach_time(datetime.now())): #get datas from the database new_data = database.retrive_data() #insert it back to the lists.... user_details = new_data[0]['userdetails'] pub_details = new_data[0]['publications'] #assigned it back to list variables for user details and publications details user_profile = user_details['username'] user_image = user_details['imageUrl'] user_id = user_details['id'] user_type = type(user_details) get_publications_data(pub_details) return render_template('callback.html', total_posts=total_posts, count_length=count_length, user_profile=user_profile, user_image=user_image, user_type=user_type, pub_name=pub_name, desrip_pub=desrip_pub, image_pub=image_pub, url_pub=url_pub, rss_links=rss_links, rss_tags=rss_tags, rss_titles=rss_titles) else: return render_template('callback.html', total_posts=total_posts, count_length=count_length, user_profile=user_profile, user_image=user_image, user_type=user_type, pub_name=pub_name, desrip_pub=desrip_pub, image_pub=image_pub, url_pub=url_pub, rss_links=rss_links, rss_tags=rss_tags, rss_titles=rss_titles)
class TestClient(unittest.TestCase): # TODO: FINISH TESTING CLIENT def setUp(self): self.client = Client(access_token="myaccesstoken") @responses.activate def test_exchange_authorization_code(self): def response_callback(payload): self.assertEqual(payload["code"][0], "mycode") self.assertEqual(payload["client_id"][0], "myclientid") self.assertEqual(payload["client_secret"][0], "myclientsecret") self.assertEqual(payload["grant_type"][0], "authorization_code") self.assertEqual(payload["redirect_uri"][0], "http://example.com/cb") data = { "token_type": "Bearer", "access_token": "myaccesstoken", "expires_at": 4575744000000, "refresh_token": "myrefreshtoken", "scope": ["basicProfile"], } return (201, data) self._mock_endpoint("POST", "/v1/tokens", response_callback, is_json=False) client = Client(application_id="myclientid", application_secret="myclientsecret") @responses.activate def test_exchange_refresh_token(self): def response_callback(payload): self.assertEqual(payload["refresh_token"][0], "myrefreshtoken") self.assertEqual(payload["client_id"][0], "myclientid") self.assertEqual(payload["client_secret"][0], "myclientsecret") self.assertEqual(payload["grant_type"][0], "refresh_token") data = { "token_type": "Bearer", "access_token": "myaccesstoken2", "expires_at": 4575744000000, "refresh_token": "myrefreshtoken2", "scope": ["basicProfile"], } return (201, data) self._mock_endpoint("POST", "/v1/tokens", response_callback, is_json=False) client = Client(application_id="myclientid", application_secret="myclientsecret") @responses.activate def test_get_current_user(self): def response_callback(payload): data = { "username": "******", "url": "https://medium.com/@nicki", "imageUrl": "https://images.medium.com/0*fkfQiTzT7TlUGGyI.png", "id": "5303d74c64f66366f00cb9b2a94f3251bf5", "name": "Nicki Minaj", } return 200, data self._mock_endpoint("GET", "/v1/me", response_callback) resp = self.client.get_current_user() self.assertEqual( resp, { "username": "******", "url": "https://medium.com/@nicki", "imageUrl": "https://images.medium.com/0*fkfQiTzT7TlUGGyI.png", "id": "5303d74c64f66366f00cb9b2a94f3251bf5", "name": "Nicki Minaj", }) @responses.activate def test_create_post(self): def response_callback(payload): self.assertEqual( payload, { "title": "Starships", "content": "<p>Are meant to flyyyy</p>", "contentFormat": "html", "tags": ["stars", "ships", "pop"], "publishStatus": "draft", }) data = { "license": "all-rights-reserved", "title": "Starships", "url": "https://medium.com/@nicki/55050649c95", "tags": ["stars", "ships", "pop"], "authorId": "5303d74c64f66366f00cb9b2a94f3251bf5", "publishStatus": "draft", "id": "55050649c95", } return 200, data self._mock_endpoint( "POST", "/v1/users/5303d74c64f66366f00cb9b2a94f3251bf5/posts", response_callback) resp = self.client.create_post("5303d74c64f66366f00cb9b2a94f3251bf5", "Starships", "<p>Are meant to flyyyy</p>", "html", tags=["stars", "ships", "pop"], publish_status="draft") self.assertEqual( resp, { "license": "all-rights-reserved", "title": "Starships", "url": "https://medium.com/@nicki/55050649c95", "tags": ["stars", "ships", "pop"], "authorId": "5303d74c64f66366f00cb9b2a94f3251bf5", "publishStatus": "draft", "id": "55050649c95", }) @responses.activate def test_upload_image(self): def response_callback(req): self.assertEqual(req.headers["Authorization"], "Bearer myaccesstoken") self.assertIn(b"Content-Type: image/png", req.body) return 200, {}, json.dumps({ "url": "https://cdn-images-1.medium.com/0*dlkfjalksdjfl.jpg", "md5": "d87e1628ca597d386e8b3e25de3a18bc", }) responses.add_callback(responses.POST, "https://api.medium.com/v1/images", content_type="application/json", callback=response_callback) resp = self.client.upload_image("./tests/test.png", "image/png") self.assertEqual( resp, { "url": "https://cdn-images-1.medium.com/0*dlkfjalksdjfl.jpg", "md5": "d87e1628ca597d386e8b3e25de3a18bc", }) def _mock_endpoint(self, method, path, callback, is_json=True): def wrapped_callback(req): if is_json: self.assertEqual(req.headers["Authorization"], "Bearer myaccesstoken") if req.body is not None: body = json.loads(req.body) if is_json else parse_qs(req.body) else: body = None status, data = callback(body) return (status, {}, json.dumps(data)) response_method = responses.GET if method == "GET" else responses.POST url = "https://api.medium.com" + path content_type = ("application/json" if is_json else "application/x-www-form-urlencoded") responses.add_callback(response_method, url, content_type=content_type, callback=wrapped_callback)