How to make this function where I can give it an argument or not - python-3.6

So I made this very small function. it is a bonehead easy function but frankly borderline my capabilities.. Im learning. The function works as expected, but I would like to go further. I would like to make it so I can either give it an argument (a username) and just get the information for that single user, or default to reporting all users. is this possible w/o starting over from what I have so far?
I have just poked around and seen some examples but nothing that I can fit into my script. that I can understand at least.
import boto3
iam = boto3.client('iam')
def user_group():
for myusers in iam.list_users()['Users']:
Group = iam.list_groups_for_user(UserName=myusers['UserName'])
print("User: " + myusers['UserName'])
for groupName in Group['Groups']:
print("Group: " + groupName['GroupName'])
print("----------------------------")
user_group()
I would like to have the ability to run this script in two fashions.
1) add an argument(s) of 'username' so I can get the response for a particular user
2) default to getting response for all users if no argument is given.

This can be done by using an argument with a default value:
def user_group(user = None):
if user is None:
print("No user")
else:
print(user)
user_group()
user_group('some user')
prints
No user
some user
In your case you may want to write
def user_group(user = None):
users_to_list = iam.list_users()['Users'] if user is None else [user]
for myusers in user_to_list:
...

Related

What should I learn to code a bot in Telegram?

I want to code and creat a bot for telegram that does these things:
1 - shows a massage to the person that hit start button
2 - then it gets a name as an input
3 - then again shows a massage
4 - getting an input
5 - at the end add the inputs to a defualt text and showing it;
for exampele:
-start
+Hi What is your name?
-X
+How old are you?
-Y
+Your name is X and you are Y years old.
My second Question is that how can I Connect to bots together, for example imagine I want to pass some input from this bot to make a poll(voting massage), in order to do that I should send the name to let's say #vote, how is that possible and what should I learn to do such things with my bot?
First you're gonna have to explore telegram bot API documentation here.
Then you should choose your programming language and the library you want to use.
There are different libraries for each language, I'm gonna name a few:
Go: https://github.com/aliforever/go-telegram-bot-api (DISCLAIMER: I wrote and maintain it)
Python: https://github.com/eternnoir/pyTelegramBotAPI
NodeJS: https://github.com/telegraf/telegraf
I'm gonna give you an example for what you want in python using pyTelegramBotAPI:
First install the library using pip:
pip install git+https://github.com/eternnoir/pyTelegramBotAPI.git
Then run this script:
import telebot
API_TOKEN = 'PLACE_BOT_TOKEN_HERE'
bot = telebot.TeleBot(API_TOKEN)
user_info = {}
def set_user_state(user_id, state):
if user_id not in user_info:
user_info[user_id] = {}
user_info[user_id]["state"] = state
def get_user_state(user_id):
if user_id in user_info:
if "state" in user_info[user_id]:
return user_info[user_id]["state"]
return "Welcome"
def set_user_info(user_id, name=None, age=None):
if name is None and age is None:
return
if name is not None:
user_info[user_id]["name"] = name
if age is not None:
user_info[user_id]["age"] = age
def get_user_info(user_id):
return user_info[user_id]
#bot.message_handler()
def echo_all(message):
user_id = message.from_user.id
if message.text == "/start":
bot.reply_to(message, "Hi What is your name?")
set_user_state(user_id, "EnterName")
return
user_state = get_user_state(user_id)
if user_state == "EnterName":
set_user_info(user_id, name=message.text)
bot.reply_to(message, "How old are you?")
set_user_state(user_id, "EnterAge")
return
if user_state == "EnterAge":
set_user_info(user_id, age=message.text)
info = get_user_info(user_id)
bot.reply_to(message, "Your name is %s and you are %s years old." %(info["name"], info["age"]))
set_user_state(user_id, "Welcome")
return
bot.reply_to(message, "To restart please send /start")
bot.infinity_polling()
Here we use a dictionary to place user state and info, you can place them anywhere like databases or json files.
Then we update a user's state based on their interactions with the bot.
For your second question, bots cannot communicate with each other so you should look for other solutions. In the case of your question where you want to create a poll, you should check sendPoll method as well as PollAnswer object which you receive when a user votes in a poll.

Fastapi alias for url/router/endpoint (set same handler for them)

How I can make alias (call the same handler) for similar url/routers like https://myapi/users/5 and https://myapi/users/me (my id placed in token and it's 5).
#router.get("/{employee_id}}", status_code=200, response_model=schemas.EmployeeOut)
async def get_employee(
employee_id: int = Path(default=..., ge=0, description='Id получаемого сотрудника.', example=8),
token: str = Depends(config.oauth2_scheme),
postgres_session: AsyncSession = Depends(database.get_db)):
try:
token_payload = services.get_token_payload(token=token)
if token_payload['role'] in (config.OPERATOR_ROLE, config.OPERATOR_ROLE, config.CLINIC_ROLE):
return (await postgres_session.execute(statement=models.employees.select().where(
models.employees.c.id == employee_id))).fetchone()
else:
raise config.known_errors['forbidden']
except Exception as error:
services.error_handler(error)
# Just as example!
#router.get("/me}", status_code=200, response_model=List[schemas.TicketOut])
async def get_me(
token: str = Depends(config.oauth2_scheme)):
token_payload = services.get_token_payload(token=token)
get_employee(employee_id=token_payload['sub'])
These functions is almost identical, the one difference is that in the second function no path parameter employee_id, but it's anyway are present in the token.
You can wonder why you need me url - it's just for convenience
It is possible. You can specify multiple decorators with API path specifications.
If you look closely at, say, router.post implementation, you will see, that the decorator returns not the wrapped function, but the original function, so you can safely pass it to another decorator.
Something like this:
#router.post('/api/action1')
#router.post('/api/action2')
def do_action():
pass
The /me endpoint needs to be above the /{employee_id}
Check out this link: https://fastapi.tiangolo.com/tutorial/path-params/#order-matters

Translate Elastic Search numeric field to a text value

I have an Elastic Search cluster with a lot of nice data, that I have created some nice Kibana dashboards for.
For the next level I decided to take a look at scripted fields to make some of the dashboards even nicer.
I want to translate some of the numeric fields into more easily understandable text values. As an example of what I want to do and what I have tried I will use the http response status code field, that most will understand quite easily but also illustrates the problem.
We log the numeric status code (200, 201, 302, 400, 404, 500 etc.) I can create a data table visualization that tells me the count for each of these status codes. But I would like to display the text reason in my dashboard.
I can create a painless script with a lot of IF statements like this:
if (doc['statuscode'].value == 200) {return "OK";}
if (doc['statuscode'].value == 201) {return "Created";}
if (doc['statuscode'].value == 400) {return "Bad Request";}
return doc['statuscode'].value;
But that isn't very nice I think.
But since I will most likely have about 150 different values and that list won't change very often, so I can live with maintaining a static map. But I haven't found any examples of implementing a map or dictionary in painless scripting.
I was thinking of implementing something like this:
Map reasonMap;
reasonMap[200] = 'OK';
reasonMap[201] = 'Created';
def reason = reasonMap[doc['statuscode'].value];
if (reason != null)
{
return reason;
}
return doc['statuscode'].value;
I haven't been able to make this code work though. The question is also if this will perform well enough for a map with up to 150 values.
Thanks
EDIT
After some trial and error... and a lot of googling, this is what I came up with that works (notice that the key needs to start with a character and not a number):
def reasonMap =
[
's200': 'OK',
's201': 'Created'
];
def key = 's' + doc['statuscode'].value
def reason = reasonMap[key];
if (reason != null)
{
return reason;
}
return doc['statuscode'].value;
Should it be
def reason = reasonMap[doc['statuscode']value];
It will perform well with a Map of 150 values.

Filtering tab completion in input task implementation

I'm currently implementing a SBT plugin for Gatling.
One of its features will be to open the last generated report in a new browser tab from SBT.
As each run can have a different "simulation ID" (basically a simple string), I'd like to offer tab completion on simulation ids.
An example :
Running the Gatling SBT plugin will produce several folders (named from simulationId + date of report generaation) in target/gatling, for example mysim-20140204234534, myothersim-20140203124534 and yetanothersim-20140204234534.
Let's call the task lastReport.
If someone start typing lastReport my, I'd like to filter out tab-completion to only suggest mysim and myothersim.
Getting the simulation ID is a breeze, but how can help the parser and filter out suggestions so that it only suggest an existing simulation ID ?
To sum up, I'd like to do what testOnly do, in a way : I only want to suggest things that make sense in my context.
Thanks in advance for your answers,
Pierre
Edit : As I got a bit stuck after my latest tries, here is the code of my inputTask, in it's current state :
package io.gatling.sbt
import sbt._
import sbt.complete.{ DefaultParsers, Parser }
import io.gatling.sbt.Utils._
object GatlingTasks {
val lastReport = inputKey[Unit]("Open last report in browser")
val allSimulationIds = taskKey[Set[String]]("List of simulation ids found in reports folder")
val allReports = taskKey[List[Report]]("List of all reports by simulation id and timestamp")
def findAllReports(reportsFolder: File): List[Report] = {
val allDirectories = (reportsFolder ** DirectoryFilter.&&(new PatternFilter(reportFolderRegex.pattern))).get
allDirectories.map(file => (file, reportFolderRegex.findFirstMatchIn(file.getPath).get)).map {
case (file, regexMatch) => Report(file, regexMatch.group(1), regexMatch.group(2))
}.toList
}
def findAllSimulationIds(allReports: Seq[Report]): Set[String] = allReports.map(_.simulationId).distinct.toSet
def openLastReport(allReports: List[Report], allSimulationIds: Set[String]): Unit = {
def simulationIdParser(allSimulationIds: Set[String]): Parser[Option[String]] =
DefaultParsers.ID.examples(allSimulationIds, check = true).?
def filterReportsIfSimulationIdSelected(allReports: List[Report], simulationId: Option[String]): List[Report] =
simulationId match {
case Some(id) => allReports.filter(_.simulationId == id)
case None => allReports
}
Def.inputTaskDyn {
val selectedSimulationId = simulationIdParser(allSimulationIds).parsed
val filteredReports = filterReportsIfSimulationIdSelected(allReports, selectedSimulationId)
val reportsSortedByDate = filteredReports.sorted.map(_.path)
Def.task(reportsSortedByDate.headOption.foreach(file => openInBrowser((file / "index.html").toURI)))
}
}
}
Of course, openReport is called using the results of allReports and allSimulationIds tasks.
I think I'm close to a functioning input task but I'm still missing something...
Def.inputTaskDyn returns a value of type InputTask[T] and doesn't perform any side effects. The result needs to be bound to an InputKey, like lastReport. The return type of openLastReport is Unit, which means that openLastReport will construct a value that will be discarded, effectively doing nothing useful. Instead, have:
def openLastReport(...): InputTask[...] = ...
lastReport := openLastReport(...).evaluated
(Or, the implementation of openLastReport can be inlined into the right hand side of :=)
You probably don't need inputTaskDyn, but just inputTask. You only need inputTaskDyn if you need to return a task. Otherwise, use inputTask and drop the Def.task.

What's wrong with my filter query to figure out if a key is a member of a list(db.key) property?

I'm having trouble retrieving a filtered list from google app engine datastore (using python for server side). My data entity is defined as the following
class Course_Table(db.Model):
course_name = db.StringProperty(required=True, indexed=True)
....
head_tags_1=db.ListProperty(db.Key)
So the head_tags_1 property is a list of keys (which are the keys to a different entity called Headings_1).
I'm in the Handler below to spin through my Course_Table entity to filter the courses that have a particular Headings_1 key as a member of the head_tags_1 property. However, it doesn't seem like it is retrieving anything when I know there is data there to fulfill the request since it never displays the logs below when I go back to iterate through the results of my query (below). Any ideas of what I'm doing wrong?
def get(self,level_num,h_key):
path = []
if level_num == "1":
q = Course_Table.all().filter("head_tags_1 =", h_key)
for each in q:
logging.info('going through courses with this heading name')
logging.info("course name filtered is %s ", each.course_name)
MANY MANY THANK YOUS
I assume h_key is key of headings_1, since head_tags_1 is a list, I believe what you need is IN operator. https://developers.google.com/appengine/docs/python/datastore/queries
Note: your indentation inside the for loop does not seem correct.
My bad apparently '=' for list is already check membership. Using = to check membership is working for me, can you make sure h_key is really a datastore key class?
Here is my example, the first get produces result, where the 2nd one is not
import webapp2 from google.appengine.ext import db
class Greeting(db.Model):
author = db.StringProperty()
x = db.ListProperty(db.Key)
class C(db.Model): name = db.StringProperty()
class MainPage(webapp2.RequestHandler):
def get(self):
ckey = db.Key.from_path('C', 'abc')
dkey = db.Key.from_path('C', 'def')
ekey = db.Key.from_path('C', 'ghi')
Greeting(author='xxx', x=[ckey, dkey]).put()
x = Greeting.all().filter('x =',ckey).get()
self.response.write(x and x.author or 'None')
x = Greeting.all().filter('x =',ekey).get()
self.response.write(x and x.author or 'None')
app = webapp2.WSGIApplication([('/', MainPage)],
debug=True)

Resources