How inline keyboard starts conversation handler, when ended edit existing message with inline keyboard - python-telegram-bot

This is the code, a message is displayed with 3 vaiables that will be filled with the buttons, except for Hostname, that button will call a Conversation Handler in order to specify the hostname.
def custom_search_ask(update: Update, _: CallbackContext) -> None:
query = update.callback_query
query.answer()
query.edit_message_text(
text=f"Please configure the custom search:\nTime: {ctimechoosen}\nHostname: {chostnamechoosen}\nSeverity: {cseveritychoosen}",
reply_markup=custom_search_keyboard())
This is the keyboard with the options
def custom_search_keyboard():
keyboard = [[InlineKeyboardButton('Time', callback_data='time_menu')],
[InlineKeyboardButton('Hostname', callback_data='hostname_search')],
[InlineKeyboardButton('Severity', callback_data='severity_menu')],
[InlineKeyboardButton('Return back', callback_data='main')]]
return InlineKeyboardMarkup(keyboard)
The button that calls the conversation handler
def hostname_ask(update: Update, _: CallbackContext) -> None:
query = update.callback_query
#query.answer()
query.edit_message_text(text=f"Selected option: {query.data} \nPlease specify hostname:")
return HOSTNAME
Conversation handler:
entry_points= [
CallbackQueryHandler(hostname_ask, pattern='^hostname_search$')
]
states = {
HOSTNAME: [
MessageHandler(filters = Filters.all , callback = custom_search_hostname_choosen)
],
Edit message and anwser with the introduced user data with new inline keyboard
def custom_search_hostname_choosen(update: Update, _: CallbackContext) -> None:
message = update.effective_message
message.edit_text(
text=f"Hostname specified \nTime: {ctimechoosen}\nHostname: {chostnamechoosen}\nSeverity: {cseveritychoosen}\nConfigure other presets or search?",
reply_markup=search_yes_no())
Really thanks for the help.
C:\Users\javie\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\telegram\ext\conversationhandler.py:287: UserWarning: If 'per_message=False', 'CallbackQueryHandler' will not be tracked for every message.
warnings.warn(
2022-05-17 13:23:56,330 - apscheduler.scheduler - INFO - Scheduler started
User ID: 873363421 with name Ferzprox inicialized the BOT with /START
2022-05-17 13:24:07,808 - telegram.ext.dispatcher - ERROR - No error handlers are registered, logging exception.
Traceback (most recent call last):
File "C:\Users\javie\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\telegram\ext\dispatcher.py", line 555, in process_update
handler.handle_update(update, self, check, context)
File "C:\Users\javie\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\telegram\ext\conversationhandler.py", line 626, in handle_update
new_state = handler.handle_update(update, dispatcher, check_result, context)
File "C:\Users\javie\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\telegram\ext\handler.py", line 198, in handle_update
return self.callback(update, context)
File "c:\Users\javie\Documents\Bot Telegram\Prod\Clean\menus.py", line 189, in custom_search_hostname_choosen
message.edit_text(
File "C:\Users\javie\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\telegram\message.py", line 2015, in edit_text
return self.bot.edit_message_text(
File "C:\Users\javie\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\telegram\bot.py", line 130, in decorator
result = func(*args, **kwargs)
File "C:\Users\javie\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\telegram\bot.py", line 2775, in edit_message_text
return self._message(
File "C:\Users\javie\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\telegram\ext\extbot.py", line 200, in _message
result = super()._message(
File "C:\Users\javie\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\telegram\bot.py", line 336, in _message
result = self._post(endpoint, data, timeout=timeout, api_kwargs=api_kwargs)
File "C:\Users\javie\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\telegram\bot.py", line 295, in _post
return self.request.post(
File "C:\Users\javie\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\telegram\utils\request.py", line 361, in post
result = self._request_wrapper(
File "C:\Users\javie\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\telegram\utils\request.py", line 279, in _request_wrapper
raise BadRequest(message)
telegram.error.BadRequest: Message can't be edited

In custom_search_hostname_choosen, the variable query will be an object of type Message - because update is of type Update and the attribute update.effective_message is a Message.
the class Message does not have a method edit_message_text. It does however have a method Message.edit_text. So you should change query.edit_message_text to query.edit_text. I also recommend to rename query to e.g. message to give it a more meaningful name.

Related

Discord.py error: "ValueError: <class 'str'> is not a valid ChannelType"

I don't understand what the error is.
> Ignoring exception in command weather:
> Traceback (most recent call last):
File "/home/timoha/discord_bot/venv/lib/python3.10/site-packages/discord/enums.py", line 168, in __call__
> return cls._enum_value_map_[value]
> KeyError: <class 'str'>
> During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/timoha/discord_bot/venv/lib/python3.10/site-packages/discord/commands/core.py", line 124, in wrapped
ret = await coro(arg)
File "/home/timoha/discord_bot/venv/lib/python3.10/site-packages/discord/commands/core.py", line 980, in _invoke
await self.callback(ctx, **kwargs)
File "/home/timoha/discord_bot/main.py", line 166, in weather
async with discord.channel.ChannelType(value=str):
File "/home/timoha/discord_bot/venv/lib/python3.10/site-packages/discord/enums.py", line 170, in __call__
> raise ValueError(f"{value!r} is not a valid {cls.__name__}")
> ValueError: <class 'str'> is not a valid ChannelType
>
> The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/timoha/discord_bot/venv/lib/python3.10/site-packages/discord/bot.py", line 1114, in invoke_application_command
await ctx.command.invoke(ctx)
File "/home/timoha/discord_bot/venv/lib/python3.10/site-packages/discord/commands/core.py", line 375, in invoke
await injected(ctx)
File "/home/timoha/discord_bot/venv/lib/python3.10/site-packages/discord/commands/core.py", line 132, in wrapped
> raise ApplicationCommandInvokeError(exc) from exc
> discord.errors.ApplicationCommandInvokeError: Application Command raised an exception: ValueError: <class 'str'> is not a valid ChannelType
Code:
#bot.slash_command(name="weather", description="Погода")
async def weather(ctx, *, city: str):
city_name = city
complete_url = base_url + "appid=" + api_key + "&q=" + city_name
response = requests.get(complete_url)
x = response.json()
channel = ctx.message
if x["cod"] != "404":
async with discord.channel.ChannelType(value=str):
value=str
y = x["главный"]
current_temperature = y["температура"]
current_temperature_celsiuis =str(round(current_temperature - 273.15))
current_pressure = y["давление"]
current_humidity = y["влажность"]
z = x["погода"]
weather_description = z[0]["описание"]
weather_description = z[0]["описание"]
embed = discord.Embed(title=f"Погода в {city_name}",
color=ctx.guild.me.top_role.color,
timestamp=ctx.message.created_at,)
embed.add_field(name="Описание", value=f"**{weather_description}**", inline=False)
embed.add_field(name="Температура(C)", value=f"**{current_temperature_celsiuis}°C**", inline=False)
embed.add_field(name="Влажность(%)", value=f"**{current_humidity}%**", inline=False)
embed.add_field(name="Atmospheric Pressure(hPa)", value=f"**{current_pressure}hPa**", inline=False)
embed.set_thumbnail(url="https://i.ibb.co/CMrsxdX/weather.png")
embed.set_footer(text=f"Запрошенный {ctx.author.name}")
await channel.send(embed=embed)
else:
await channel.send("Город не найден.")
I tried to change a lot of things, but I still can't figure out what the problem is.
There's a few issues with your code - that error is probably just the first one. I've attempted to rewrite what you've provided with some explanation but hopefully it replicates what you're trying to do.
#bot.slash_command(name="weather", description="Погода")
async def weather(ctx, *, city: str):
# as we're doing an API call here - let's defer so the interaction doesn't timeout
await ctx.defer()
# no reason to redefine another variable called 'city_name' equal to 'city' - just use 'city' everywhere
# could also use a f-string for creating the URL here
# complete_url = f"{base_url}appid={api_key}&q={city}"
complete_url = base_url + "appid=" + api_key + "&q=" + city
response = requests.get(complete_url)
json_response = response.json()
if json_response["cod"] == "404":
# if it's 404, let's send the error message and return early
# means we don't have a big nested "if" block
await channel.send("Город не найден.")
return
y = json_response["главный"]
z = json_response["погода"]
current_temperature = y["температура"]
current_temperature_celsiuis =str(round(current_temperature - 273.15))
current_pressure = y["давление"]
current_humidity = y["влажность"]
weather_description = z[0]["описание"]
weather_description = z[0]["описание"]
# create the embed
embed = discord.Embed(
title=f"Погода в {city}",
color=ctx.guild.me.top_role.color,
timestamp=ctx.message.created_at
)
embed.add_field(name="Описание", value=f"**{weather_description}**", inline=False)
embed.add_field(name="Температура(C)", value=f"**{current_temperature_celsiuis}°C**", inline=False)
embed.add_field(name="Влажность(%)", value=f"**{current_humidity}%**", inline=False)
embed.add_field(name="Atmospheric Pressure(hPa)", value=f"**{current_pressure}hPa**", inline=False)
embed.set_thumbnail(url="https://i.ibb.co/CMrsxdX/weather.png")
embed.set_footer(text=f"Запрошенный {ctx.author.name}")
# now let's send our response
# ctx.send will send to the channel that the user used the slash command in
await ctx.send(embed=embed)
The ctx variable docs.
What I changed:
removed creating a variable called city_name that was exactly equal to city - seemed redundant
added ctx.defer() - if our code takes a little while it's good to defer so the interaction doesn't timeout
removed channel = ctx.message. We can get the channel later if we need to (we don't in this case) but this was setting it equal to the message that invoked the application command (which isn't really a message) so we aren't accomplishing anything here anyways
if we get a 404 response; send error message and return. Better to do this than have a big nested if block in my opinion.
I also renamed x to json_response as I prefer descriptive variable names but I gave up on y and z.
got rid of the whatever the async with statement was trying to accomplish
used ctx.send(embed=embed) at the bottom to send your created embed to the channel that the user used the application command in
Hopefully, this is what you want it to do and hopefully you understand what's going on a bit now. It might be worth having a look through some of the examples and documentation to get a better grasp on how it all works.
Another change you could make, is swapping out requests for aiohttp-requests to make non-blocking API calls.
I took advantage of your help, and I am grateful to you in many ways, but I am just starting my way in programming and learning from a real example. So I corrected my code to yours and I was given a new set of errors, which I also can't figure out a little.
gnoring exception in command weather: Traceback (most recent call
last):
File "/home/timoha/discord_bot/venv/lib/python3.10/site-packages/discord/commands/core.py", line 124, in wrapped
ret = await coro(arg)
File "/home/timoha/discord_bot/venv/lib/python3.10/site-packages/discord/commands/core.py", line 980, in _invoke
await self.callback(ctx, **kwargs) File
"/home/timoha/discord_bot/main.py", line 162, in weather
y = json_response["главный"] KeyError: 'главный'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/timoha/discord_bot/venv/lib/python3.10/site-packages/discord/bot.py", line 1114, in invoke_application_command
await ctx.command.invoke(ctx)
File "/home/timoha/discord_bot/venv/lib/python3.10/site-packages/discord/commands/core.py", line 375, in invoke
await injected(ctx)
File "/home/timoha/discord_bot/venv/lib/python3.10/site-packages/discord/commands/core.py", line 132, in wrapped
raise ApplicationCommandInvokeError(exc) from exc
discord.errors.ApplicationCommandInvokeError: Application Command
raised an exception: KeyError: 'главный'

DataprocCreateClusterOperator fails due to TypeError

EDIT 1: The problem is related to the field "initialization_actions". Originally I'd put a String there, now I gave it the object it's asking for:
from google.cloud.dataproc_v1beta2 import NodeInitializationAction
CLUSTER_CONFIG = {
...
"initialization_actions": NodeInitializationAction({
"executable_file": <string>})]
}
Unfortunately it's still complaining:
ERROR - Parameter to MergeFrom() must be instance of same class: expected google.cloud.dataproc.v1beta2.NodeInitializationAction got NodeInitializationAction.
I am trying to deploy a Dataproc cluster with airflow.providers.google.cloud.operators.dataproc.DataprocCreateClusterOperator, but I get a cryptic TypeError.
Here is the task definition:
CLUSTER_CONFIG = {
"config_bucket": <my_bucket>,
"temp_bucket": <my_bucket>,
"master_config": {
"num_instances": 1,
"machine_type_uri": "c2-standard-8",
"disk_config": {"boot_disk_type": "pd-standard", "boot_disk_size_gb": 1024},
},
"initialization_actions": [<string>],
}
create_cluster = DataprocCreateClusterOperator(
task_id="create_cluster",
project_id=PROJECT_ID,
cluster_config=CLUSTER_CONFIG,
region=REGION,
cluster_name=CLUSTER_NAME,
metadata=[("ENV", ENV)],
dag=dag)
Traceback:
Traceback (most recent call last)
File "/usr/local/lib/airflow/airflow/models/taskinstance.py", line 985, in _run_raw_tas
result = task_copy.execute(context=context
File "/usr/local/lib/airflow/airflow/providers/google/cloud/operators/dataproc.py", line 603, in execut
cluster = self._create_cluster(hook
File "/usr/local/lib/airflow/airflow/providers/google/cloud/operators/dataproc.py", line 540, in _create_cluste
metadata=self.metadata
File "/usr/local/lib/airflow/airflow/providers/google/common/hooks/base_google.py", line 425, in inner_wrappe
return func(self, *args, **kwargs
File "/usr/local/lib/airflow/airflow/providers/google/cloud/hooks/dataproc.py", line 304, in create_cluste
metadata=metadata
File "/opt/python3.6/lib/python3.6/site-packages/google/cloud/dataproc_v1beta2/services/cluster_controller/client.py", line 412, in create_cluste
request = clusters.CreateClusterRequest(request
File "/opt/python3.6/lib/python3.6/site-packages/proto/message.py", line 506, in __init_
pb_value = marshal.to_proto(pb_type, value
File "/opt/python3.6/lib/python3.6/site-packages/proto/marshal/marshal.py", line 208, in to_prot
pb_value = rule.to_proto(value
File "/opt/python3.6/lib/python3.6/site-packages/proto/marshal/rules/message.py", line 32, in to_prot
return self._descriptor(**value
TypeError: Parameter to MergeFrom() must be instance of same class: expected google.cloud.dataproc.v1beta2.NodeInitializationAction got str
The field `initialization_actions" is not a list of strings, but a list of dicts:
"initialization_actions": [{"executable_file": <string>}]

AWS Lambda EC2-Instances Client Timeout Error

It's very often for me to get error when trying to stop or start ec2-instances through AWS Lambda. Quite strange for me, because sometimes it works (for both start and stop ec2-instances).
The error I get is like below. When I run test on Lambda console, most of the time it successfully executed. But when I run it through AWS Event Rules (CloudWatch), it's very often the function got fail.
This is my code on line 48
[ERROR] ConnectTimeoutError: Connect timeout on endpoint URL: "https://ec2.ap-southeast-2.amazonaws.com/"
Traceback (most recent call last):
File "/var/task/lambda_function.py", line 48, in lambda_handler
if stop_ec2_instances():
File "/var/task/lambda_function.py", line 155, in stop_ec2_instances
ec2_client.stop_instances(InstanceIds=ec2_instances)
File "/var/task/botocore/client.py", line 316, in _api_call
return self._make_api_call(operation_name, kwargs)
File "/var/task/botocore/client.py", line 621, in _make_api_call
http, parsed_response = self._make_request(
File "/var/task/botocore/client.py", line 641, in _make_request
return self._endpoint.make_request(operation_model, request_dict)
File "/var/task/botocore/endpoint.py", line 102, in make_request
return self._send_request(request_dict, operation_model)
File "/var/task/botocore/endpoint.py", line 136, in _send_request
while self._needs_retry(attempts, operation_model, request_dict,
File "/var/task/botocore/endpoint.py", line 253, in _needs_retry
responses = self._event_emitter.emit(
File "/var/task/botocore/hooks.py", line 356, in emit
return self._emitter.emit(aliased_event_name, **kwargs)
File "/var/task/botocore/hooks.py", line 228, in emit
return self._emit(event_name, kwargs)
File "/var/task/botocore/hooks.py", line 211, in _emit
response = handler(**kwargs)
File "/var/task/botocore/retryhandler.py", line 183, in __call__
if self._checker(attempts, response, caught_exception):
File "/var/task/botocore/retryhandler.py", line 250, in __call__
should_retry = self._should_retry(attempt_number, response,
File "/var/task/botocore/retryhandler.py", line 277, in _should_retry
return self._checker(attempt_number, response, caught_exception)
File "/var/task/botocore/retryhandler.py", line 316, in __call__
checker_response = checker(attempt_number, response,
File "/var/task/botocore/retryhandler.py", line 222, in __call__
return self._check_caught_exception(
File "/var/task/botocore/retryhandler.py", line 359, in _check_caught_exception
raise caught_exception
File "/var/task/botocore/endpoint.py", line 200, in _do_get_response
http_response = self._send(request)
File "/var/task/botocore/endpoint.py", line 269, in _send
return self.http_session.send(request)
File "/var/task/botocore/httpsession.py", line 287, in send
raise ConnectTimeoutError(endpoint_url=request.url, error=e)
This is my code for start & stop the instances:
Even, I already move instantiation og ec2_res ec2_client inside the function but it did not help.,
def start_ec2_instances():
try:
ec2_res = boto3.resource('ec2', region_name="ap-southeast-2")
ec2_client = boto3.client('ec2', region_name="ap-southeast-2")
ec2_client.start_instances(InstanceIds=ec2_instances)
for ec2_id in ec2_instances:
instance = ec2_res.Instance(id=ec2_id)
logger.info("Waiting instance " + ec2_id + " to start")
instance.wait_until_running()
return True
except bex.ClientError as err:
logger.error(err.response['Error']['Message'])
return False
def stop_ec2_instances():
try:
ec2_res = boto3.resource('ec2', region_name="ap-southeast-2")
ec2_client = boto3.client('ec2', region_name="ap-southeast-2")
ec2_client.stop_instances(InstanceIds=ec2_instances)
for ec2_id in ec2_instances:
instance = ec2_res.Instance(id=ec2_id)
logger.info("Waiting instance " + ec2_id + " to stop")
instance.wait_until_stopped()
return True
except bex.ClientError as err:
logger.error(err.response['Error']['Message'])
return False
If any one of you ever face the same guys?
Thanks
Edit: I set function timeout to 8 minutes. In normal condition, time required to execute the function is less than 5 minutes.
Additional note:
Sometimes I work using VPN (south-east-2) in which this VPN is in a different region from the region I live. Instances (and another components) also deployed on this region VPN (south-east-2).
Your code to start and stop the instance looks right to me. The timeout is happening because the time taken to perform your operation is not getting completed in the configured timeout for your lambda function.
You can measure what is the time taken for your function by simply subtracting the time between start and stop of the function.
The default timeout is 3 seconds. So you should consider increasing this timeout interval for your lambda function. Say to 5 minutes.
Please note that the maximum value for this timeout is 300 seconds(15 minutes) and you can not configure value higher than this. I am sure the above code would complete within that limit and hence it should not be a problem for you.
How do I increase my timeout interval for my lambda function?
There are multiple ways to do this. By AWS CLI, AWS console, or probably some other way.
In AWS Console you can do like this:
Click on the Save button after doing this change.
Hope this helps.

How to provide the "result.has_errors()" and "result.has_validation_errors()" attributes when using import_data method for Django import_export

I need to make changes to a csv file being imported using the module import_Export for Django. I implement the import_data method for this but get the error 'Dataset' object has no attribute 'has_errors'
Traceback (most recent call last):
File "C:\Program Files\Python36\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
response = get_response(request)
File "C:\Program Files\Python36\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Program Files\Python36\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Program Files\Python36\lib\site-packages\django\utils\decorators.py", line 130, in _wrapped_view
response = view_func(request, *args, **kwargs)
File "C:\Program Files\Python36\lib\site-packages\django\views\decorators\cache.py", line 44, in _wrapped_view_func
response = view_func(request, *args, **kwargs)
File "C:\Program Files\Python36\lib\site-packages\django\contrib\admin\sites.py", line 231, in inner
return view(request, *args, **kwargs)
File "C:\Program Files\Python36\lib\site-packages\import_export\admin.py", line 316, in import_action
if not result.has_errors() and not result.has_validation_errors():
Exception Type: AttributeError at /admin/engine/mtg/import/
Exception Value: 'Dataset' object has no attribute 'has_errors'
How can I provide the result.has_error() and result.has_validation_errors() when I return my customized dataset to avoid this error? Here is where I implement the method
Admin
class ModelResource(resources.ModelResource):
def import_data(self, dataset, dry_run=False, raise_errors=True,use_transactions=None, collect_failed_rows=False, **kwargs):
new_dataset = do_stuff(dataset)
return new_dataset
The documentation states that the first thing that the import_data method does is create a "result" instance containing error information. I'm assuming this is what I need maybe? But I don't know how to gain access to it or return it with my new dataset[Import Data workflow][1]
[1]: https://django-import-export.readthedocs.io/en/latest/import_workflow.html?highlight=before)import
You shouldn't need to override has_errors() and has_validation_errors() because the logic should be handled for you.
Generally you shouldn't be over-riding import_data() because this is where the import logic happens. Pass a valid Dataset object into import_data() as the first arg. I suggest having a quick look at the source, because this will clarify what is going on.
If you need to modify the imported data, then there are several hooks you can use. This is where you subclass the base Resource and add your own logic.
This example is based on the django-import-export example app:
class BookResource(resources.ModelResource):
def before_import_row(self, row, row_number=None, **kwargs):
"""
Override to add additional logic.
"""
pass
def before_save_instance(self, instance, using_transactions, dry_run):
"""
Override to add additional logic.
"""
pass
class Meta:
model = Book
fields = ('id', 'author_email', 'price')
Then you can call this with:
rows = [
('book1', 'email#example.com', '10.25'),
('book2', 'email#example.com', '10.25'),
('book1', 'email#example.com', '10.25'),
]
dataset = tablib.Dataset(*rows, headers=['name', 'author_email', 'price'])
book_resource = BookResource()
result = book_resource.import_data(dataset)
print(result.totals)

gdata.docs.client.DocsClient

I have the following code, reads oauth2 token form file, then try's to perform a doc's list query to find a specific spreadsheet that I want to copy, however no matter what I try the code either errors out or returns with an object containing no document data.
I am using gdata.docs.client.DocsClient which as far as I can tell is version 3 of the API
def CreateClient():
"""Create a Documents List Client."""
client = gdata.docs.client.DocsClient(source=config.APP_NAME)
client.http_client.debug = config.DEBUG
# Authenticate the user with CLientLogin, OAuth, or AuthSub.
if os.path.exists(config.CONFIG_FILE):
f = open(config.CONFIG_FILE)
tok = pickle.load(f)
f.close()
client.auth_token = tok.auth_token
return client
1st query attempt
def get_doc():
new_api_query = gdata.docs.client.DocsQuery(title='RichSheet', title_exact=True, show_collections=True)
d = client.GetResources(q = new_api_query)
this fails with the following stack trace
Traceback (most recent call last):
File "/Users/richard/PycharmProjects/reportone/make_my_report.py", line 83, in <module>
get_doc()
File "/Users/richard/PycharmProjects/reportone/make_my_report.py", line 57, in get_doc
d = client.GetResources(q = new_api_query)
File "/Users/richard/PycharmProjects/reportone/gdata/docs/client.py", line 151, in get_resources
**kwargs)
File "/Users/richard/PycharmProjects/reportone/gdata/client.py", line 640, in get_feed
**kwargs)
File "/Users/richard/PycharmProjects/reportone/gdata/docs/client.py", line 66, in request
return super(DocsClient, self).request(method=method, uri=uri, **kwargs)
File "/Users/richard/PycharmProjects/reportone/gdata/client.py", line 267, in request
uri=uri, auth_token=auth_token, http_request=http_request, **kwargs)
File "/Users/richard/PycharmProjects/reportone/atom/client.py", line 115, in request
self.auth_token.modify_request(http_request)
File "/Users/richard/PycharmProjects/reportone/gdata/gauth.py", line 1047, in modify_request
token_secret=self.token_secret, verifier=self.verifier)
File "/Users/richard/PycharmProjects/reportone/gdata/gauth.py", line 668, in generate_hmac_signature
next, token, verifier=verifier)
File "/Users/richard/PycharmProjects/reportone/gdata/gauth.py", line 629, in build_oauth_base_string
urllib.quote(params[key], safe='~')))
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib.py", line 1266, in quote
if not s.rstrip(safe):
AttributeError: 'bool' object has no attribute 'rstrip'
Process finished with exit code 1
then my second attempt
def get_doc():
other = gdata.docs.service.DocumentQuery(text_query='RichSheet')
d = client.GetResources(q = other)
this returns an ResourceFeed object, but has no content. I have been through the source code for these function but thing are not any obvious.
Have i missed something ? or should i go back to version 2 of the api ?

Resources