How do I get the Swagger-generated Python client to work? - python

I have generated the python client and server from https://editor.swagger.io/ - and the server runs correctly with no editing, but I can't seem to get the client to communicate with it - or with anything.
I suspect I'm doing something really silly but the examples I've found on the Internet either don't work or appear to be expecting that I understand how to craft the object. Here's my code (I've also tried sending nothing, a string, etc):
import time
import swagger_client
import json
from swagger_client.rest import ApiException
from pprint import pprint
# Configure OAuth2 access token for authorization: petstore_auth
swagger_client.configuration.access_token = 'special-key'
# create an instance of the API class
api_instance = swagger_client.PetApi()
d = '{"id": 0,"category": {"id": 0,"name": "string"},"name": "doggie","photoUrls": ["string"], "tags": [ { "id": 0, "name": "string" } ], "status": "available"}'
python_d = json.loads(d)
print( json.dumps(python_d, sort_keys=True, indent=4) )
body = swagger_client.Pet(python_d) # Pet | Pet object that needs to be added to the store
try:
# Add a new pet to the store
api_instance.add_pet(body)
except ApiException as e:
print("Exception when calling PetApi->add_pet: %s\n" % e)
I'm using python 3.6.4 and when the above runs I get:
Traceback (most recent call last):
File "petstore.py", line 14, in <module>
body = swagger_client.Pet(python_d) # Pet | Pet object that needs to be added to the store
File "/Users/bombcar/mef/petstore/python-client/swagger_client/models/pet.py", line 69, in __init__
self.name = name
File "/Users/bombcar/mef/petstore/python-client/swagger_client/models/pet.py", line 137, in name
raise ValueError("Invalid value for `name`, must not be `None`") # noqa: E501
ValueError: Invalid value for `name`, must not be `None`
I feel I'm making an incredibly basic mistake, but I've literally copied the JSON from https://editor.swagger.io/ - but since I can't find an actually working example I don't know what I'm missing.

The Python client generator produces object-oriented wrappers for the API. You cannot post a dict or a JSON string directly, you need to create a Pet object using the generated wrapper:
api_instance = swagger_client.PetApi()
pet = swagger_client.Pet(name="doggie", status="available",
photo_urls=["http://img.example.com/doggie.png"],
category=swagger_client.Category(id=42))
response = api_instance.add_pet(pet)

I got similar issue recently and finally fixed by upgrading python version in my local. I generated python-flask-server zip file from https://editor.swagger.io/. Then I set up the environment locally with py 3.6.10. I got same error when parsing input by using "Model_Name.from_dict()", telling me
raise ValueError("Invalid value for `name`, must not be `None`") # noqa: E501
ValueError: Invalid value for `name`, must not be `None`
Then I upgraded to python 3.7.x, the issue was resolved. I know that your problem is not related to version, however, just in case anyone got similar issue and seeking for help could see this answer.

Related

Tweepy Api Python Response, need help decoding the response

I trust all is well with you and yours. Thank you for taking a moment to read through this and I apologize if this is a repeat (if it is point me to the right spot and I will read through that!)
I am trying to hit the twitter api via tweepy (cause im to new to figure out python and the twitter official api) and return a result in a useable format.
import Auth_Codes
import json
twitter_auth_keys = {
"consumer_key" : Auth_Codes.consumer_key,
"consumer_secret" : Auth_Codes.consumer_secret,
"access_token" : Auth_Codes.access_token,
"access_token_secret" : Auth_Codes.access_token_secret
}
auth = tweepy.OAuthHandler(
twitter_auth_keys["consumer_key"],
twitter_auth_keys["consumer_secret"]
)
auth.set_access_token(
twitter_auth_keys["access_token"],
twitter_auth_keys["access_token_secret"]
)
api = tweepy.API(auth)
#api.search_tweets(q = "Aztar")
searched_tweets = [tweet for tweet in tweepy.Cursor(api.search_tweets,
q = "What you want to search",
lang = 'en',
result_type = 'recent',
count = 1)
.items(1)]
print(searched_tweets)
print(type(searched_tweets))
when this is executed, I get a very large response that I cannot fully post here.
it is also type: <class 'list'>
I hope that added the spoiler button as intended. My issue is that I have tried in several different ways to convert this into an actual json, and I am struggling as every guide I am following online leads me to a dead end (granted I am learning lots!). In node.js, I would normally leverage a map and sort it that way. Is there something similar I can do here? Not all the data is relevant to me.
Thanks in advance, and really sorry about not knowing how to add a spoiler button if it is at all possible.
I have added the following to it:
searched_tweets_dict = json.loads(searched_tweets)
print(searched_tweets_dict)
and the result is the following error code:
Traceback (most recent call last):
File "E:\Dropbox\Backup\Github\Python\Mid_Journey\Search.py", line 33, in <module>
searched_tweets_dict = json.loads(searched_tweets)
File "C:\Pthyon_3.10\lib\json\__init__.py", line 339, in loads
raise TypeError(f'the JSON object must be str, bytes or bytearray, '
TypeError: the JSON object must be str, bytes or bytearray, not list
Why are you using a Cursor if you are only requesting one tweet?
And why don't you just use the generator instead of creating that list?
Anyway, the json object is already included in the Tweepy objects (._json).
cursor = tweepy.Cursor(
api.search_tweets,
q = "What you want to search",
lang = 'en',
result_type = 'recent',
count = 1
)
for tweet in cursor.items(1):
print(tweet._json)

python-ldap3 is unable to add user to and existing LDAP group

I am able successfully connect using LDAP3 and retrieve my LDAP group members as below.
from ldap3 import Server, Connection, ALL, SUBTREE
from ldap3.extend.microsoft.addMembersToGroups import ad_add_members_to_groups as addMembersToGroups
>>> conn = Connection(Server('ldaps://ldap.****.com:***', get_info=ALL),check_names=False, auto_bind=False,user="ANT\*****",password="******", authentication="NTLM")
>>>
>>> conn.open()
>>> conn.search('ou=Groups,o=****.com', '(&(cn=MY-LDAP-GROUP))', attributes=['cn', 'objectclass', 'memberuid'])
it returns True and I can see members by printing
conn.entries
>>>
The above line says MY-LDAP-GROUP exists and returns TRUE while searching but throws LDAP group not found when I try to an user to the group as below
>>> addMembersToGroups(conn, ['myuser'], 'MY-LDAP-GROUP')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/****/anaconda3/lib/python3.7/site-packages/ldap3/extend/microsoft/addMembersToGroups.py", line 69, in ad_add_members_to_groups
raise LDAPInvalidDnError(group + ' not found')
ldap3.core.exceptions.LDAPInvalidDnError: MY-LDAP-GROUP not found
>>>
The above line says MY-LDAP-GROUP exists and returns TRUE
Returning True just means that the search succeeded. It doesn't mean that anything was found. Is there anything in conn.entries?
But I suspect your real problem is something different. If this is the source code for ad_add_members_to_groups, then it is expecting the distinguishedName of the group (notice the parameter name group_dn), but you're passing the cn (common name). For example, your code should be something like:
addMembersToGroups(conn, ['myuser'], 'CN=MY-LDAP-GROUP,OU=Groups,DC=example,DC=com')
If you don't know the DN, then ask for the distinguishedName attribute from the search.
A word of warning: that code for ad_add_members_to_groups retrieves all the current members before adding the new member. You might run into performance problems if you're working with groups that have large membership because of that (e.g. if the group has 1000 members, it will load all 1000 before adding anyone). You don't actually need to do that (you can add a new member without looking at the current membership). I think what they're trying to avoid is the error you get when you try to add someone who is already in the group. But I think there are better ways to handle that. It might not matter to you if you're only working with small groups.
After so many trial and errors, I got frustrated and used the older python-ldap library to add existing users. Now my code is a mixture of ldap3 and ldap.
I know this is not what the OP has desired. But this may help someone.
Here the user Dinesh Kumar is already part of a group group1. I am trying to add him
to another group group2 which is successful and does not disturb the existing group
import ldap
import ldap.modlist as modlist
def add_existing_user_to_group(user_name, user_id, group_id):
"""
:return:
"""
# ldap expects a byte string.
converted_user_name = bytes(user_name, 'utf-8')
converted_user_id = bytes(user_id, 'utf-8')
converted_group_id = bytes(group_id, 'utf-8')
# Add all the attributes for the new dn
ldap_attr = {}
ldap_attr['uid'] = converted_user_name
ldap_attr['cn'] = converted_user_name
ldap_attr['uidNumber'] = converted_user_id
ldap_attr['gidNumber'] = converted_group_id
ldap_attr['objectClass'] = [b'top', b'posixAccount', b'inetOrgPerson']
ldap_attr['sn'] = b'Kumar'
ldap_attr['homeDirectory'] = b'/home/users/dkumar'
# Establish connection to server using ldap
conn = ldap.initialize(server_uri, bytes_mode=False)
bind_resp = conn.simple_bind_s("cn=admin,dc=testldap,dc=com", "password")
dn_new = "cn={},cn={},ou=MyOU,dc=testldap,dc=com".format('Dinesh Kumar','group2')
ldif = modlist.addModlist(ldap_attr)
try:
response = conn.add_s(dn_new, ldif)
except ldap.error as e:
response = e
print(" The response is ", response)
conn.unbind()
return response

Fixing "TypeError: '_io.TextIOWrapper' object is not subscriptable" in python script

I'm trying to store some data in a config.json for a bot that I'm working on, but I keep getting the same error every time I attempt to run it.
I'm running Python 3.7.3, latest version of the rewrite. I've attempted moving around the config.json file around to no avail. I'm probably missing something incredibly obvious, but I don't know what.
Where the exception is being raised:
with open("config.json", "r") as infile:
try:
CONFIG = json.load(infile)
_ = infile["token"]
_ = infile["owner"]
except (KeyError, FileNotFoundError):
raise EnvironmentError(
"Your config.json file is either missing, or incomplete. Check your config.json and ensure it has the keys 'token' and 'owner_id'"
)
Expected Result: Code pulls token and owner from the file, and proceeds to run the bot.
Actual Result: Bot doesn't get launched. Traceback output -
File "/Users/prismarine/Desktop/Project_Prismarine/core.py", line 11, in <module>
_ = infile["token"]
TypeError: '_io.TextIOWrapper' object is not subscriptable
You're trying to call the file handle as a dictionary instead of the JSON dictionary stored in CONFIG. Instead, try:
with open("config.json", "r") as infile:
try:
CONFIG = json.load(infile)
token = CONFIG["token"]
owner = CONFIG["owner"]
except (KeyError, FileNotFoundError):
raise EnvironmentError(
"Your config.json file is either missing, or incomplete. Check your config.json and ensure it has the keys 'token' and 'owner_id'"
)
Note also that underscores are usually used as variable names if they won't be used anywhere, and that the underscore would be assigned to CONFIG['token'], then immediately reassigned to CONFIG['owner'] in your case. I gave them some new unique variable names if you're planning to use them later.

How to add members to a group using directory api and python?

I am trying to get my head around migrating to google admin sdk. I am trying to add members to a group (mailing list) using python. I have figured out how to create the group, but can't figure out how to add members. I have read this page: https://developers.google.com/admin-sdk/directory/v1/reference/members/insert but cannot figure out how to map it to python (I have little experience with REST or python, I'm trying to learn).
This is how I am trying to do it:
import httplib2
from apiclient.discovery import build
from oauth2client.client import SignedJwtAssertionCredentials
keyFile = file(p12File, 'rb')
key = keyFile.read()
keyFile.close()
credentials = SignedJwtAssertionCredentials(serviceAccount,
key,
scope,
prn=superAdmin)
http = httplib2.Http()
httplib2.debuglevel = False #change this to True if you want to see the output
http = credentials.authorize(http=http)
directoryService = build(serviceName='admin', version='directory_v1', http=http)
# THIS DOES NOT WORK
groupinfo = {'email': 'wibble#XXX.co.uk'}
directoryService.groups().insert(groupKey='mygroup#XXX.co.uk', body=groupinfo).execute()
When I run that I get:
Traceback (most recent call last):
File "add-member-to-group.py", line 58, in <module>
directoryService.groups().insert(groupKey='mygroup#XXX.co.uk', body=groupinfo).execute()
File "/usr/local/lib/python2.7/dist-packages/googleapiclient/discovery.py", line 604, in method
raise TypeError('Got an unexpected keyword argument "%s"' % name)
TypeError: Got an unexpected keyword argument "groupKey"
I would be grateful if someone could help me to figure out how to do this.
After further hunting around I worked it out. That last line should have been:
directoryService.members().insert(groupKey='mygroup#XXX.co.uk', body=groupinfo).execute()
i.e. directoryService.members()... not directoryService.groups()...
The examples here helped me to work it out.

Passing a variable to a JSON web service

I am accessing the class from the code api_service.py, which can be found here. When I call the first function, I have no problem, because no variables are passed:
from api_service import ApiService
import json
def main():
api_key = *removed*
access_token = *removed*
calling = ApiService(api_key,access_token)
survey_list = calling.get_survey_list()
But when I use the same type of routine as above to call a function from ApiService that requires a variable, I'm told that I should pass an object.
survey_details = calling.get_survey_details("1234")
survey_details = json.loads(json.dumps(survey_details))
print survey_details
The specific error message:
{u'status': 3, u'errmsg': u"Value '1234' for field '_data' is not of type object"}
Details for the get_survey_details aspect of the SurveyMonkey API are here, although I think a python-guru can solve this without knowing about the API.
This is a javascript/json object:
{field:'value'}
You have passed a string which, doesn't count as an "object" for these purposes.
Note that the error message is being generated by the service you are accessing. This question would be better directed to the creator of the service.

Categories

Resources