- Writing a Script in Python
- Using Spyder which is part of the Anaconda suite
- Organizing your code to run as a script
- Methods
- Libraries
- External
- Flexible code — running with arguments
- Challenge
- External Arguments
- Challenge
- ArgParse: Safe use of external arguments
- Пишем простой скрипт на Python
- 5. Создание базовых скриптов#
Writing a Script in Python
So far, we have covered the main programming structures used in Python. We will now put that together in a script which can be run on demand.
Using Spyder which is part of the Anaconda suite
Spyder is an application where you can edit and run your Python scripts. As part of Anaconda, there are a large number of scientific packages which come pre-installed, to make it easier for scientists getting started in programming.
We will run through a brief overview of the panels:
- Left panel: Editor
- this is a special type of editor which understands python
- as you type, possible options may appear to assist you
- key words are highlighted to help readability and understanding
- Top Right panel: Help
- Variable explorer: as a program runs, variables are loaded here with their values
- File explorer: list of files in the current working directory
- Help: documentation and tutorials
- Bottom Right panel: Console
- Python console: standard python command-line (like typing python in a terminal window)
- IPython console: interactive python (like Jupyter cells)
Organizing your code to run as a script
In Spyder, a new file is created when you first open the application. This is called temp.py.
- Create a new project under Projects ->New Project in your required directory
- Save the temp file to hello.py
- Type the following (the HelloWorld mantra):
- Click on the green arrow in the top toolbar. A popup window may appear which allows you to change a few things. Accept the defaults and click OK
- Have a look in the IPython console window and you should see the output similar to:
runfile('D:/Projects/Python-tutorial/examples/hello.py', wdir='D:/Projects/Python-tutorial/examples') Hello World
Methods
Recall that it is useful to group code into methods so replace the code with:
def hello(): """Print "Hello World" and return None""" print("Hello World") # main program starts here hello()
- Run again as before and the same output will appear in the console window.
- As we have run the output in the IPython console window and we have defined a method called hello() , what will happen if we just type hello() in the console?
Libraries
We will now use a library as we did in previous lessons. Take note of the order.
- The import statement goes at the top
- The methods should come next but should be before the instructions (main body)
- The instructions for running the methods go at the end
import math def hello(): """Print "Hello World" and return None""" print("Hello World") def get_pi(): """Get value of pi""" return math.pi # main program starts here hello() print('pi is', get_pi())
After running this script, you can type help(math) in the IPython console — just as we did in Jupyter but it has to be loaded with import math first
External
Before we move on, there is an extra line recommended when running the script from outside this environment:
Insert this line above hello() then indent the following code:
# main program starts here if __name__ == '__main__': hello() print('pi is', get_pi())
This allows us to run from a terminal window: python hello.py
Flexible code — running with arguments
So how would we make this script more dynamic?
We will change the hello() method to take a variable name .
def hello(name): """Print "Hello " and a name and return None""" print("Hello", name) . hello("Josephine")
After running the script, in the IPython console, type hello(«Napoleon») or any other name
Challenge
Change the call function to loop over a few names (your first spamming script!).
External Arguments
But these are still variables defined in the script, how do we pass variables in from the command line? There is a library called sys which allows your script to read from the system in which it is running. Variables passed in are called arguments and are strings which are stored in a list called sys.argv
In a new script called sysargs.py, type:
import sys # main program starts here if __name__ == '__main__': program = sys.argv[0] print("Program running is:", program)
Only one argument is present and that is the name of the program which is running — this will always be the case. We will now include two extra arguments so add some extra lines to the code:
import sys # main program starts here if __name__ == '__main__': program = sys.argv[0] print("Program running is:", program) #Now check for extra arguments if (len(sys.argv) == 3): argument1 = sys.argv[1] argument2 = sys.argv[2] print("Arguments:", argument1, argument2)
- In Spyder, we can add the extra arguments by:
- Run ->Configure
- Check Command line options then enter “hello world” in the text field
- Click on OK
Challenge
Return to your hello.py script and allow the name to be entered as an argument
import sys import re def hello(name): """Print "Hello " and a name and return None""" print("Hello", name) def valid(name): '''Only words with characters, underscores or hyphens are valid''' # Provide a validity check to ensure bad stuff is not passed in # Introducing a new library called `re` match = re.match(r'^[A-Za-z0-9_\-]+$', name) if (match): isvalid = True else: isvalid = False return isvalid # main program starts here if __name__ == '__main__': randomname = None #ensure that this variable is clean to start if (len(sys.argv) > 1): #test whether any arguments have been passed in randomname = sys.argv[1] # Check that name is a valid string if (randomname is not None and valid(randomname)): hello(randomname) else: print("No name passed in")
WARNING!! Allowing information to be passed into your script this way can be DANGEROUS. The argv array should never be read directly without checking the validity of the contents first.
ArgParse: Safe use of external arguments
To help you with checking that nothing malicious is passed into your script, use a library called argparse . The argparse module makes it easy to write user-friendly command-line interfaces. The program defines what arguments it requires, and argparse will figure out how to parse those out of sys.argv . The argparse module also automatically generates help and usage messages and issues errors when users give the program invalid arguments.
We will update the previous script:
import argparse import re def hello(name): """Print "Hello " and a name and return None""" print("Hello", name) def valid(name): '''Only words with characters, underscores or hyphens are valid''' # Provide a validity check to ensure bad stuff is not passed in # Introducing a new library called `re` match = re.match(r'^[A-Za-z0-9_\-]+$', name) if (match): isvalid = True else: isvalid = False return isvalid # main program starts here if __name__ == '__main__': #Setup the argument parser class parser = argparse.ArgumentParser(prog='Hello program', description='''\ Reads a name and says hello ''') #We use the optional switch -- otherwise it is mandatory parser.add_argument('--randomname', action='store', help='A name', default="Josephine") #Run the argument parser args = parser.parse_args() #Extract our value or default randomname = args.randomname # Check that name is a valid string if (randomname is not None and valid(randomname)): hello(randomname) else: print("No name passed in")
- As before, use the Run ->Configure to add Command-line options —randomname Napoleon , ‘OK’
- Now Run
We will now move onto the next lesson Handling errors
Пишем простой скрипт на Python
Здарова, щеглы, сегодня мы своими руками будем писать скрипт на Python. Нам понадобятся: интерпретатор Python 3 под «какая-там-у-вас-ОС», текстовый редактор с подсветкой синтаксиса, например, Sublime Text, Google, упаковка прамирацетама, бутылка минеральной воды и 60 минут свободного времени.
Перед тем как писать скрипт, мы должны определиться, что он вообще будет делать. Делать он будет следующее: получив на вход домен и диапазон IP-адресов, многопоточно проходить список этих адресов, совершать HTTP-запрос к каждому, в попытках понять, на каком же из них размещен искомый домен. Зачем это нужно? Бывают ситуации, когда IP-адрес домена закрыт Cloudflare, или Stormwall, или Incapsula, или еще чем-нибудь, WHOIS история не выдает ничего интересного, в DNS-записях такая же канитель, а, внезапно, один из поддоменов ресолвится в адрес из некоторой подсети, которая не принадлежит сервису защиты. И в этот момент нам становится интересно, вдруг и основной домен размещен в той же самой подсети.Погнали, сразу выпиваем половину бутылки воды, и пишем следующий код:
Ни одного комментария, какие-то import, непонятные аргументы командной строки и еще эти две последние строчки. Но будьте спокойны, все нормально, это я вам как мастер программирования на Python с 30-минутным стажем говорю. Тем более, как известно, Google не врет, а официальная документация по Python — это вообще неоспоримая истина.
Так что же мы все-таки сделали в вышеописанном фрагменте кода? Мы подключили модули для работы с аргументами коммандной строки, модули для логирования (потокобезопасные между прочим!), модуль для работы с SSL (для одной мелочи, связанной с HTTPS-запросами), модуль для создания пула потоков, и, наконец, модули для совершения HTTP-запросов, работы с IP-адресами и двухсторонней очередью (по поводу различных типов импорта можно почитать здесь).
После этого мы, в соответствии с документацией по модулю argparse, создали вспомогательную функцию, которая будет обрабатывать аргументы, переданные скрипту при запуске из командной строки. Как видите, в скрипте будет предусмотрена работа со списком доменов/IP-диапазонов, а также возможность фильтрации результатов по ключевым словам и по кодам состояния HTTP и еще пара мелочей, как, например, смена User-Agent и опциональная проверка HTTPS-версии искомого ресурса. Последние две строки в основном используются для разделения кода, который будет выполнен при запуске самого скрипта и при импортировании в другой скрипт. В общем тут все сложно, все так пишут. Мы тоже так будем писать. Можно было бы немного модифицировать этот код, например, добавив возврат разных статусов системе в зависимости от того, как отработала функция main, добавить argv в качестве аргумента, и так далее, но мы изучаем Python только 10 минут и ленимся вчитываться в документацию.Делаем перерыв и выпиваем глоток освежающей минеральной воды.
5. Создание базовых скриптов#
Если говорить в целом, то скрипт — это обычный файл. В этом файле хранится последовательность команд, которые необходимо выполнить.
Начнем с базового скрипта. Выведем на стандартный поток вывода несколько строк.
Для этого надо создать файл access_template.py с таким содержимым:
access_template = ['switchport mode access', 'switchport access vlan <>', 'switchport nonegotiate', 'spanning-tree portfast', 'spanning-tree bpduguard enable'] print('\n'.join(access_template).format(5))
Сначала элементы списка объединяются в строку, которая разделена символом \n , а в строку подставляется номер VLAN, используя форматирование строк.
После этого надо сохранить файл и перейти в командную строку.
Так выглядит выполнение скрипта:
$ python access_template.py switchport mode access switchport access vlan 5 switchport nonegotiate spanning-tree portfast spanning-tree bpduguard enable
Ставить расширение .py у файла не обязательно, но, если вы используете Windows, то это желательно делать, так как Windows использует расширение файла для определения того, как обрабатывать файл.
В курсе все скрипты, которые будут создаваться, используют расширение .py. Можно сказать, что это «хороший тон» — создавать скрипты Python с таким расширением.