Django Value Error attempted import beyond top level - python
I'm trying to run a suite of tests for a django project I've been brought into. Running the tests in my Power Shell environment using python manage.py test --settings=tRecorderApi.settings_test returns the following output:
Creating test database for alias 'default'...
DEBUG 2018-03-26 09:05:56,124 base 276900 275184 Configuring Raven for host: http://sentry:9000
EEEEEEEEEEEEEEEE
======================================================================
ERROR: file_transfer (unittest.loader._FailedTest)
----------------------------------------------------------------------
ImportError: Failed to import test module: file_transfer
Traceback (most recent call last):
File "C:\Program Files (x86)\Python36-32\lib\unittest\loader.py", line 462, in _find_test_path
package = self._get_module_from_name(name)
File "C:\Program Files (x86)\Python36-32\lib\unittest\loader.py", line 369, in _get_module_from_name
__import__(name)
File "C:\Users\dipinton\tE-backend\tRecorderApi\api\file_transfer\__init__.py", line 1, in <module>
from .FileUtility import *
File "C:\Users\dipinton\tE-backend\tRecorderApi\api\file_transfer\FileUtility.py", line 12, in <module>
from ..models.language import Language
ValueError: attempted relative import beyond top-level package
======================================================================
ERROR: models (unittest.loader._FailedTest)
----------------------------------------------------------------------
ImportError: Failed to import test module: models
Traceback (most recent call last):
File "C:\Program Files (x86)\Python36-32\lib\unittest\loader.py", line 462, in _find_test_path
package = self._get_module_from_name(name)
File "C:\Program Files (x86)\Python36-32\lib\unittest\loader.py", line 369, in _get_module_from_name
__import__(name)
File "C:\Users\dipinton\tE-backend\tRecorderApi\api\models\__init__.py", line 1, in <module>
from .book import Book
File "C:\Users\dipinton\tE-backend\tRecorderApi\api\models\book.py", line 4, in <module>
class Book(models.Model):
File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\db\models\base.py", line 118, in __new__
"INSTALLED_APPS." % (module, name)
RuntimeError: Model class models.book.Book doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS.
----------------------------------------------------------------------
Ran 16 tests in 0.000s
FAILED (errors=16)
System check identified no issues (0 silenced).
Destroying test database for alias 'default'...
The rest of the test results all look the same as the first one with the ValueError: attempted relative import beyond top-level package.
My folder structure looks like this (the only important files are under the first tRecorderApi folder):
C:.
| .gitignore
| api_spec.txt
| postgres-setup
| README.md
| __init__.py
|
+---InstallationScripts
| | README.md
| |
| +---translationExchangeRpi
| | | install.deb
| | | prepare.sh
| | | uninstall.sh
| | |
| | \---install
| | +---DEBIAN
| | | control
| | | postinst
| | |
| | \---tmp
| | \---tex_install
| | +---config
| | | dhcpcd.conf
| | | hosts
| | | tex_autorun.sh
| | |
| | \---TranslationExchange
| | | docker-compose.yml
| | | Dockerfile
| | |
| | +---ap
| | | dnsmasq.conf
| | | Dockerfile
| | | entrypoint.sh
| | | hostapd
| | | hostapd.conf
| | |
| | \---config
| | | config.py
| | | requirements.txt
| | | rootCA.crt
| | | self-signed.conf
| | | server.crt
| | | server.key
| | | ssl-params.conf
| | |
| | \---nginx
| | trapi.conf
| |
| \---translationExchangeVM
| | install
| | prepare
| | software
| | uninstall
| |
| +---autorun
| | tex_autorun.sh
| |
| \---TranslationExchange
| | docker-compose.yml
| | Dockerfile
| |
| \---config
| | config.py
| | requirements.txt
| | rootCA.crt
| | self-signed.conf
| | server.crt
| | server.key
| | ssl-params.conf
| |
| \---nginx
| trapi.conf
|
+---tRecorderApi
| | books.json
| | db.sqlite3
| | langnames.json
| | manage.py
| | requirements.txt
| | swaggerAPI.yaml
| | wmta.py
| | __init__.py
| |
| +---api
| | | admin.py
| | | apps.py
| | | parsers.py
| | | serializers.py
| | | tasks.py
| | | urls.py
| | |
| | +---file_transfer
| | | | ArchiveIt.py
| | | | ArchiveProject.py
| | | | AudioUtility.py
| | | | Download.py
| | | | FileTransfer.py
| | | | FileUtility.py
| | | | tinytag.py
| | | | TrIt.py
| | | | Upload.py
| | | | ZipIt.py
| | | | __init__.py
| | | |
| | | \---__pycache__
| | | ArchiveIt.cpython-36.pyc
| | | ArchiveProject.cpython-36.pyc
| | | AudioUtility.cpython-36.pyc
| | | Download.cpython-36.pyc
| | | FileTransfer.cpython-36.pyc
| | | FileUtility.cpython-36.pyc
| | | tinytag.cpython-36.pyc
| | | TrIt.cpython-36.pyc
| | | Upload.cpython-36.pyc
| | | ZipIt.cpython-36.pyc
| | | __init__.cpython-36.pyc
| | |
| | +---migrations
| | | | 0001_initial.py
| | | | __init__.py
| | | |
| | | \---__pycache__
| | | 0001_initial.cpython-36.pyc
| | | __init__.cpython-36.pyc
| | |
| | +---models
| | | | anthology.py
| | | | book.py
| | | | chapter.py
| | | | chunk.py
| | | | comment.py
| | | | language.py
| | | | mode.py
| | | | project.py
| | | | take.py
| | | | version.py
| | | | __init__.py
| | | |
| | | \---__pycache__
| | | anthology.cpython-36.pyc
| | | book.cpython-36.pyc
| | | chapter.cpython-36.pyc
| | | chunk.cpython-36.pyc
| | | comment.cpython-36.pyc
| | | language.cpython-36.pyc
| | | mode.cpython-36.pyc
| | | project.cpython-36.pyc
| | | take.cpython-36.pyc
| | | version.cpython-36.pyc
| | | __init__.cpython-36.pyc
| | |
| | +---templates
| | | index.html
| | |
| | +---tests
| | | | tests_books.py
| | | | tests_get_projects.py
| | | | tests_upload.py
| | | | test_api_anthologies.py
| | | | test_api_books.py
| | | | test_api_chapters.py
| | | | test_api_chunks.py
| | | | test_api_comments.py
| | | | test_api_languages.py
| | | | test_api_modes.py
| | | | test_api_projects.py
| | | | test_api_takes.py
| | | | test_api_versions.py
| | | | test_api_zip.py
| | | | __init__.py
| | | |
| | | \---__pycache__
| | | tests_books.cpython-36.pyc
| | | tests_get_projects.cpython-36.pyc
| | | tests_upload.cpython-36.pyc
| | | test_api_anthologies.cpython-36.pyc
| | | test_api_books.cpython-36.pyc
| | | test_api_chapters.cpython-36.pyc
| | | test_api_chunks.cpython-36.pyc
| | | test_api_comments.cpython-36.pyc
| | | test_api_languages.cpython-36.pyc
| | | test_api_modes.cpython-36.pyc
| | | test_api_projects.cpython-36.pyc
| | | test_api_takes.cpython-36.pyc
| | | test_api_versions.cpython-36.pyc
| | | test_api_zip.cpython-36.pyc
| | | __init__.cpython-36.pyc
| | |
| | +---views
| | | | anthology.py
| | | | book.py
| | | | chapter.py
| | | | chunk.py
| | | | comment.py
| | | | exclude_files.py
| | | | file_upload.py
| | | | frontend.py
| | | | helpers.py
| | | | index.py
| | | | language.py
| | | | mode.py
| | | | project.py
| | | | push_takes.py
| | | | resumable_upload.py
| | | | source_file.py
| | | | source_file_upload.py
| | | | stitch_takes.py
| | | | take.py
| | | | tr.py
| | | | update_project_takes.py
| | | | user.py
| | | | version.py
| | | | zip.py
| | | | __init__.py
| | | |
| | | \---__pycache__
| | | anthology.cpython-36.pyc
| | | book.cpython-36.pyc
| | | chapter.cpython-36.pyc
| | | chunk.cpython-36.pyc
| | | comment.cpython-36.pyc
| | | exclude_files.cpython-36.pyc
| | | file_upload.cpython-36.pyc
| | | frontend.cpython-36.pyc
| | | helpers.cpython-36.pyc
| | | index.cpython-36.pyc
| | | language.cpython-36.pyc
| | | mode.cpython-36.pyc
| | | project.cpython-36.pyc
| | | push_takes.cpython-36.pyc
| | | resumable_upload.cpython-36.pyc
| | | source_file.cpython-36.pyc
| | | source_file_upload.cpython-36.pyc
| | | stitch_takes.cpython-36.pyc
| | | take.cpython-36.pyc
| | | tr.cpython-36.pyc
| | | version.cpython-36.pyc
| | | zip.cpython-36.pyc
| | | __init__.cpython-36.pyc
| | |
| | \---__pycache__
| | admin.cpython-36.pyc
| | serializers.cpython-36.pyc
| | tasks.cpython-36.pyc
| | urls.cpython-36.pyc
| | __init__.cpython-36.pyc
| |
| +---static
| | | loader.gif
| | | resumable.js
| | |
| | \---chunks
| | +---nt
| | | +---1co
| | | | chunks.json
| | | |
| | | +---1jn
| | | | chunks.json
| | | |
| | | +---1pe
| | | | chunks.json
| | | |
| | | +---1th
| | | | chunks.json
| | | |
| | | +---1ti
| | | | chunks.json
| | | |
| | | +---2co
| | | | chunks.json
| | | |
| | | +---2jn
| | | | chunks.json
| | | |
| | | +---2pe
| | | | chunks.json
| | | |
| | | +---2th
| | | | chunks.json
| | | |
| | | +---2ti
| | | | chunks.json
| | | |
| | | +---3jn
| | | | chunks.json
| | | |
| | | +---act
| | | | chunks.json
| | | |
| | | +---col
| | | | chunks.json
| | | |
| | | +---eph
| | | | chunks.json
| | | |
| | | +---gal
| | | | chunks.json
| | | |
| | | +---heb
| | | | chunks.json
| | | |
| | | +---jas
| | | | chunks.json
| | | |
| | | +---jhn
| | | | chunks.json
| | | |
| | | +---jud
| | | | chunks.json
| | | |
| | | +---luk
| | | | chunks.json
| | | |
| | | +---mat
| | | | chunks.json
| | | |
| | | +---mrk
| | | | chunks.json
| | | |
| | | +---phm
| | | | chunks.json
| | | |
| | | +---php
| | | | chunks.json
| | | |
| | | +---rev
| | | | chunks.json
| | | |
| | | +---rom
| | | | chunks.json
| | | |
| | | \---tit
| | | chunks.json
| | |
| | \---ot
| | +---1ch
| | | chunks.json
| | |
| | +---1ki
| | | chunks.json
| | |
| | +---1sa
| | | chunks.json
| | |
| | +---2ch
| | | chunks.json
| | |
| | +---2ki
| | | chunks.json
| | |
| | +---2sa
| | | chunks.json
| | |
| | +---amo
| | | chunks.json
| | |
| | +---dan
| | | chunks.json
| | |
| | +---deu
| | | chunks.json
| | |
| | +---ecc
| | | chunks.json
| | |
| | +---est
| | | chunks.json
| | |
| | +---exo
| | | chunks.json
| | |
| | +---ezk
| | | chunks.json
| | |
| | +---ezr
| | | chunks.json
| | |
| | +---gen
| | | chunks.json
| | |
| | +---hab
| | | chunks.json
| | |
| | +---hag
| | | chunks.json
| | |
| | +---hos
| | | chunks.json
| | |
| | +---isa
| | | chunks.json
| | |
| | +---jdg
| | | chunks.json
| | |
| | +---jer
| | | chunks.json
| | |
| | +---job
| | | chunks.json
| | |
| | +---jol
| | | chunks.json
| | |
| | +---jon
| | | chunks.json
| | |
| | +---jos
| | | chunks.json
| | |
| | +---lam
| | | chunks.json
| | |
| | +---lev
| | | chunks.json
| | |
| | +---mal
| | | chunks.json
| | |
| | +---mic
| | | chunks.json
| | |
| | +---nam
| | | chunks.json
| | |
| | +---neh
| | | chunks.json
| | |
| | +---num
| | | chunks.json
| | |
| | +---oba
| | | chunks.json
| | |
| | +---pro
| | | chunks.json
| | |
| | +---psa
| | | chunks.json
| | |
| | +---rut
| | | chunks.json
| | |
| | +---sng
| | | chunks.json
| | |
| | +---zec
| | | chunks.json
| | |
| | \---zep
| | chunks.json
| |
| +---tRecorderApi
| | | celery.py
| | | settings.py
| | | settings_test.py
| | | urls.py
| | | wsgi.py
| | | __init__.py
| | |
| | \---__pycache__
| | celery.cpython-36.pyc
| | settings.cpython-36.pyc
| | settings_test.cpython-36.pyc
| | urls.cpython-36.pyc
| | wsgi.cpython-36.pyc
| | __init__.cpython-36.pyc
| |
| \---__pycache__
| __init__.cpython-36.pyc
|
\---__pycache__
__init__.cpython-36.pyc
Based on similar questions, I suspect this may have something to do with the __init__.py files in each folder. I already removed one from the 'api' folder, which should be the root of the project (that's why I started receiving the value error). Before that, I was getting the error shown in the second test where it's complaining that my models are not in my list of installed apps in my settings file. The settings file I use can be seen below:
"""
Django settings for tRecorderApi project.
Generated by 'django-admin startproject' using Django 1.11.2.
For more information on this file, see
https://docs.djangoproject.com/en/1.11/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.11/ref/settings/
"""
import os
import raven
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '&9e^=922_&wi-bw#bbe$id#r$7hb(im03nrow5w#tgg8##hfd('
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = ['192.168.96.21', '172.19.145.91',
'172.19.145.88', 'localhost', '127.0.0.1', 'te.loc']
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'corsheaders',
'api',
'django_celery_results',
'drf_yasg',
'raven.contrib.django.raven_compat',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
"""REST_FRAMEWORK = {
# Use Django's standard `django.contrib.auth` permissions,
# or allow read-only access for unauthenticated users.
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'
]
}"""
CORS_ORIGIN_ALLOW_ALL = True
ROOT_URLCONF = 'tRecorderApi.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'api/templates'), ],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'tRecorderApi.wsgi.application'
# Database
# https://docs.djangoproject.com/en/1.11/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3')
}
}
# DATABASES = {
# 'default': {
# 'ENGINE': 'django.db.backends.postgresql_psycopg2',
# 'NAME': 'postgres',
# 'USER': 'postgres',
# 'HOST': 'db',
# 'PORT': 5432,
# }
# }
RAVEN_CONFIG = {
'dsn': 'http://2e7130f730eb42dfa6bbe67875dfd8ee:15b0167a7b714b7697a63e6678081e3b#sentry:9000/2',
# If you are using git, you can also automatically configure the
# release based on the git info.
'release': raven.fetch_git_sha(os.path.abspath(os.pardir)),
}
LOGGING = {
'version': 1,
'disable_existing_loggers': True,
'root': {
'level': 'WARNING',
'handlers': ['sentry'],
},
'formatters': {
'verbose': {
'format': '%(levelname)s %(asctime)s %(module)s '
'%(process)d %(thread)d %(message)s'
},
},
'handlers': {
'sentry': {
# To capture more than ERROR, change to WARNING, INFO, etc.
'level': 'INFO',
'class': 'raven.contrib.django.raven_compat.handlers.SentryHandler',
'tags': {'custom-tag': 'x'},
},
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
'formatter': 'verbose'
}
},
'loggers': {
'django.db.backends': {
'level': 'ERROR',
'handlers': ['console'],
'propagate': False,
},
'raven': {
'level': 'DEBUG',
'handlers': ['console'],
'propagate': False,
},
'sentry.errors': {
'level': 'DEBUG',
'handlers': ['console'],
'propagate': False,
},
},
}
# Password validation
# https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/1.11/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.11/howto/static-files/
STATIC_ROOT = 'static'
STATIC_URL = '/static/'
# MEDIA_ROOT = 'media'
# MEDIA_URL = '/media/'
REACT_APP_DIR = os.path.join(BASE_DIR, 'frontend')
STATICFILES_DIRS = [
os.path.join(REACT_APP_DIR, 'build', 'static'),
]
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
SECURE_SSL_REDIRECT = False
SESSION_COOKIE_SECURE = False
CSRF_COOKIE_SECURE = False
# celery
CELERY_BROKER_URL = 'amqp://te:te#rabbit:5672'
CELERY_RESULT_BACKEND = 'redis://redis:6379/0'
CELERY_ACCEPT_CONTENT = ['pickle']
CELERY_TASK_SERIALIZER = 'pickle'
CELERY_RESULT_SERIALIZER = 'pickle'
CELERY_IGNORE_RESULT = False
CELERY_TASK_TRACK_STARTED = True
My question here is do I need to remove all of the __init__.py files? Is there something in settings that I need to change to get the tests to run properly? Or is my issue something completely different from what I'm thinking it is?
Looks like I was able to solve my own problem. In this case, I did a git reset to get my init.py file back into my api directory. From there, I set the DJANG_SETTINGS_MODULE environment variable to point to my custom settings file. I use a Windows 10 machine so the command looked like this:
set DJANGO_SETTINGS_MODULE=tRecorderApi.settings_test
Running the two steps above got my tests to run without the Value Error.
Related
How to classify the image data from the folders?
It is our folder tree. dataset/ | | |-----train/ | | | |--dog/ | | | | | |--German Shepherd/ | | | | | | | |-- image1.png | | | |-- image2.png | | | |-- ... | | | | | |--Bulldog/ | | |--Labrador Retriever/ | | |--Poodle/ | | |--Chihuahua/ | | |--... | | | |--cat/ | | | | | |--Siamese cat/ | | |--British Shorthair/ | | |--Maine Coon/ | | |--Persian cat/ | | |--Ragdoll/ | | |--... | |-----test/ | |--... how can be classify it with tensorflow-python ? I am not using any pre-trained model then how can be classify it ?
Updating values onto an ASCII art without changing the format [closed]
Closed. This question needs to be more focused. It is not currently accepting answers. Want to improve this question? Update the question so it focuses on one problem only by editing this post. Closed 6 months ago. Improve this question I am exploring ways on bash as well as on Python to print out values onto an ASCII art for improving the readability. The one difficulty is to update values without changing the format of the art. The ascii art looks something like this: ======================================================== | | | | | | | | | | | | | CPU | | GPU | | HDD | | | | | | | | | | | | | | ${CPU_W}W | | | | | | ${CPU_Freq}MHz| | | |Avail Mem${size}G| | | |${GPU_W}W | | Used Mem${size}G| | | |${GPU}Mhz | | | | | | | | | | | | | | | | | | | | | | | | | | | ======================================================== So far, I was able to prevent the format from changing on Bash. But doing this, is not allowing me to change the values. cat << "EOF" ======================================================== | | | | | | | | | | | | | CPU | | GPU | | HDD | | | | | | | | | | | | | | ${CPU_W}W | | | | | | ${CPU_Freq}MHz| | | |Avail Mem${size}G| | | |${GPU_W}W | | Used Mem${size}G| | | |${GPU}Mhz | | | | | | | | | | | | | | | | | | | | | | | | | | | ======================================================== EOF Without cat << "EOF" ...ascii art.... EOF, I can update the values but the format keeps changing . Is there anyway to keep the same format even with the values changing? Thanks in advance.
I'm not exactly sure what you're trying to achieve... so? f = """ ======================================================== | | | | | | | | | | | | | CPU | | GPU | | HDD | | | | | | | | | | | | | |{cpuW:>15}| | | | | |{cpuF:>15}| | | |Avail Mem{ramA:>8}| | | |{gpuW:>10}| | Used Mem{ramU:>8}| | | |{gpuF:>10}| | | | | | | | | | | | | | | | | | | | | | | | | | | ======================================================== """ def main(): cpuW = 12.2 cpuF = 2354 gpuW = 15.2 gpuF = 789 ramA = 16.1 ramU = 12.2 d = { 'cpuW': f'{cpuW:.1f} W ', 'cpuF': f'{cpuF:d} MHz ', 'gpuW': f'{gpuW:.1f} W ', 'gpuF': f'{gpuF:d} MHz ', 'ramA': f' {ramA:.1f} GB', 'ramU': f' {ramU:.1f} GB', } out = f.format_map(d) print(out) if __name__ == '__main__': main() Output is: ======================================================== | | | | | | | | | | | | | CPU | | GPU | | HDD | | | | | | | | | | | | | | 12.2 W | | | | | | 2354 MHz | | | |Avail Mem 16.1 GB| | | | 15.2 W | | Used Mem 12.2 GB| | | | 789 MHz | | | | | | | | | | | | | | | | | | | | | | | | | | | ========================================================
In python, you can use the format and str.ljust method. format(value[, format_spec]) Convert a value to a “formatted” representation, as controlled by format_spec. The interpretation of format_spec will depend on the type of the value argument; however, there is a standard formatting syntax that is used by most built-in types: Format Specification Mini-Language. It depends on what you want the notation to be (e.g how many zeros, ecc...). here is an example: >>> characters = 10 >>> format(32,".2E").zfill(characters) '003.20E+01' >>> #first number is the minimum number of characters >>> format(32,"{0}.2E".format(characters)) ' 3.20E+01' or, with fstrings: >>> f"{32:.2E}" '3.20E+01' Example on how to use it in ascii art: >>> def create_ascii_art(CPU_W,CPU_freq,GPU_W, ... GPU,Free_Mem,Used_Mem): ... CPU_W,CPU_freq,GPU_W,GPU,Free_Mem,Used_Mem = map(float,(CPU_W,CPU_freq,GPU_W,GPU,Free_Mem,Used_Mem)) ... return f''' ...======================================================== ...| | | | | | ...| | | | | | ...| CPU | | GPU | | HDD | ...| | | | | | ...| | | | | | ...|{CPU_W:12.2E}W | | | | | ...|{CPU_freq:12.2E}MHz| | | |Avail Mem{Free_Mem:7.3}G| ...| | |{GPU_W:8.2E}W | | Used Mem{Used_Mem:7.3}G| ...| | |{GPU:6.0E}Mhz | | | ...| | | | | | ...| | | | | | ...| | | | | | ...| | | | | | ...========================================================''' >>> print(create_ascii_art(1,1,1,1,1,1)) output: ======================================================== | | | | | | | | | | | | | CPU | | GPU | | HDD | | | | | | | | | | | | | | 1.00E+00W | | | | | | 1.00E+00MHz| | | |Avail Mem 1.0G| | | |1.00E+00W | | Used Mem 1.0G| | | | 1E+00Mhz | | | | | | | | | | | | | | | | | | | | | | | | | | | ========================================================
The "format" does not change; the display width of the strings in the here document depends on the values of the variables. You'll want to make sure the values are padded to the expected width (or truncated, if necessary). A slightly tortured way to accomplish this is to pad the actual values: #!/bin/bash : printf -v CPU_W '%8s' "$CPU_W" printf -v CPU_Freq '%11s' "$CPU_Freq" printf -v GPU_W '%8s' "$GPU_W" printf -v GPU '%6s' "$GPU" printf -v size '%7s' "$size" cat <<EOF ======================================================== | | | | | | | | | | | | | CPU | | GPU | | HDD | | | | | | | | | | | | | | ${CPU_W}W | | | | | | ${CPU_Freq}MHz| | | |Avail Mem${size}G| | | |${GPU_W}W | | Used Mem${size}G| | | |${GPU}Mhz | | | | | | | | | | | | | | | | | | | | | | | | | | | ======================================================== EOF Probably a better solution altogether is to use printf directly to format the output. (Personally, I would perceive a notable reduction in my blood pressure if you removed at least half of the repetitive "ASCII art", which would somewhat tidy up the necessary code, too.) We can't know what values these variables contain; if they are integers, maybe experiment with i instead of s for the printf format code, or correspondingly f or perhaps g for floating-point values. If you need truncation, try %8.8 instead of %8, etc. An altogether nicer approach is to use a library for producing this format. I can't recommend any particular one for Bash; for Python, look at tabulate.
Get urls of opened tabs in browser pywinauto python
Am trying to get all tabs in web browser Brave / Chrome window But don;t understand how to get the list. I am using python 3.8.13. Tried with tabs = dlg.Pane9.iter_descendants() but it results an object like <generator object BaseWrapper.iter_descendants at 0x0000024AC8FD0580> and there is no list inside. dlg.print_control_identifiers() looks like this ['TESTING - Brave - TESTING', 'TESTING - Brave - TESTINGPane', 'Pane', 'Pane0', 'Pane1'] child_window(title="TESTING - Brave - TESTING", control_type="Pane") | | Document - 'Powered by WordPress Username or Email Address admin Password Log In Lost your password? ← Go to Sosinventory ' (L961, T-972, R1919, B-31) | ['Powered by WordPress Username or Email Address admin Password Log In Lost your password? ← Go to Sosinventory Document', 'Document', 'Powered by WordPress Username or Email Address admin Password Log In Lost your password? ← Go to Sosinventory '] | child_window(title="Powered by WordPress Username or Email Address admin Password Log In Lost your password? ← Go to Sosinventory ", auto_id="40111424", control_type="Document") | | | | Hyperlink - 'Powered by WordPress' (L1398, T-925, R1482, B-840) | | ['Hyperlink', 'Powered by WordPressHyperlink', 'Powered by WordPress', 'Hyperlink0', 'Hyperlink1'] | | child_window(title="Powered by WordPress", control_type="Hyperlink") | | | | Static - 'Username or Email Address' (L1305, T-788, R1475, B-768) | | ['Static', 'Username or Email Address', 'Username or Email AddressStatic', 'Static0', 'Static1'] | | child_window(title="Username or Email Address", control_type="Text") | | | | Edit - 'Username or Email Address' (L1305, T-765, R1575, B-724) | | ['Edit', 'Username or Email AddressEdit', 'Edit0', 'Edit1'] | | child_window(title="Username or Email Address", auto_id="user_login", control_type="Edit") | | | | Static - 'Password' (L1305, T-708, R1363, B-688) | | ['Static2', 'Password', 'PasswordStatic'] | | child_window(title="Password", control_type="Text") | | | | Edit - 'Password' (L1305, T-685, R1575, B-644) | | ['PasswordEdit', 'Edit2'] | | child_window(title="Password", auto_id="user_pass", control_type="Edit") | | | | Button - 'Show password' (L1535, T-685, R1575, B-644) | | ['Show password', 'Show passwordButton', 'Button', 'Button0', 'Button1'] | | child_window(title="Show password", control_type="Button") | | | | CheckBox - 'Remember Me' (L1305, T-626, R1321, B-609) | | ['Remember Me', 'CheckBox', 'Remember MeCheckBox'] | | child_window(title="Remember Me", auto_id="rememberme", control_type="CheckBox") | | | | Button - 'Log In' (L1513, T-629, R1575, B-596) | | ['Log InButton', 'Log In', 'Button2'] | | child_window(title="Log In", auto_id="wp-submit", control_type="Button") | | | | Hyperlink - 'Lost your password?' (L1304, T-537, R1421, B-519) | | ['Hyperlink2', 'Lost your password?', 'Lost your password?Hyperlink'] | | child_window(title="Lost your password?", control_type="Hyperlink") | | | | Hyperlink - '← Go to Sosinventory' (L1304, T-501, R1429, B-483) | | ['Hyperlink3', '← Go to SosinventoryHyperlink', '← Go to Sosinventory'] | | child_window(title="← Go to Sosinventory", control_type="Hyperlink") | | Pane - '' (L961, T-1080, R1919, B-31) | ['Pane2', 'Username or Email AddressPane', 'Username or Email AddressPane0', 'Username or Email AddressPane1'] | | TitleBar - '' (L0, T0, R0, B0) | ['TitleBar'] | | | | Menu - 'System' (L961, T-1072, R983, B-1050) | | ['Menu', 'SystemMenu', 'System', 'System0', 'System1'] | | child_window(title="System", auto_id="MenuBar", control_type="MenuBar") | | | | | | MenuItem - 'System' (L961, T-1072, R983, B-1050) | | | ['SystemMenuItem', 'MenuItem', 'System2', 'MenuItem0', 'MenuItem1'] | | | child_window(title="System", control_type="MenuItem") | | | | Button - 'Minimize' (L0, T0, R0, B0) | | ['Minimize', 'MinimizeButton', 'Button3', 'Minimize0', 'Minimize1', 'MinimizeButton0', 'MinimizeButton1'] | | child_window(title="Minimize", control_type="Button") | | | | Button - 'Maximize' (L0, T0, R0, B0) | | ['Maximize', 'MaximizeButton', 'Button4', 'Maximize0', 'Maximize1', 'MaximizeButton0', 'MaximizeButton1'] | | child_window(title="Maximize", control_type="Button") | | | | Button - 'Close' (L0, T0, R0, B0) | | ['Button5', 'Close', 'CloseButton', 'Close0', 'Close1', 'CloseButton0', 'CloseButton1'] | | child_window(title="Close", control_type="Button") | | Pane - 'Brave' (L961, T-1080, R1919, B-31) | ['Brave', 'BravePane', 'Pane3', 'Brave0', 'Brave1'] | child_window(title="Brave", control_type="Pane") | | | | Pane - '' (L961, T-1080, R1919, B-31) | | ['Pane4', 'Username or Email AddressPane2'] | | | | | | Pane - '' (L1736, T-1079, R1919, B-1050) | | | ['Pane5'] | | | | | | | | MenuItem - 'Search tabs' (L1736, T-1079, R1781, B-1050) | | | | ['Search tabsMenuItem', 'Search tabs', 'MenuItem2'] | | | | child_window(title="Search tabs", control_type="MenuItem") | | | | | | | | Button - 'Minimize' (L1781, T-1079, R1827, B-1050) | | | | ['Minimize2', 'MinimizeButton2', 'Button6'] | | | | child_window(title="Minimize", control_type="Button") | | | | | | | | Button - 'Maximize' (L1827, T-1079, R1873, B-1050) | | | | ['Maximize2', 'MaximizeButton2', 'Button7'] | | | | child_window(title="Maximize", control_type="Button") | | | | | | | | Button - 'Close' (L1873, T-1079, R1919, B-1050) | | | | ['Button8', 'Close2', 'CloseButton2'] | | | | child_window(title="Close", control_type="Button") | | | | | | Pane - '' (L961, T-1071, R1919, B-31) | | | ['Pane6', 'Username or Email AddressPane3'] | | | | | | | | Pane - '' (L961, T-1071, R1919, B-972) | | | | ['Pane7'] | | | | | | | | | | TabControl - '' (L961, T-1071, R1736, B-1040) | | | | | ['TabControlNew Tab', 'TabControl'] | | | | | | | | | | | | Pane - '' (L961, T-1071, R1448, B-1040) | | | | | | ['Pane8'] | | | | | | | | | | | | | | Pane - '' (L961, T-1071, R1448, B-1040) | | | | | | | ['Pane9'] | | | | | | | | | | | | | | | | TabItem - 'TESTING' (L961, T-1071, R1209, B-1040) | | | | | | | | ['TESTING', 'TabItem', 'TESTINGTabItem', 'TESTING0', 'TESTING1', 'TabItem0', 'TabItem1', 'TESTINGTabItem0', 'TESTINGTabItem1'] | | | | | | | | child_window(title="TESTING", control_type="TabItem") | | | | | | | | | | | | | | | | TabItem - 'TESTING' (L1200, T-1071, R1448, B-1040) | | | | | | | | ['TESTING2', 'TabItem2', 'TESTINGTabItem2'] | | | | | | | | child_window(title="TESTING", control_type="TabItem") | | | | | | | | | | | | | | | | | | Button - 'Close' (L1420, T-1071, R1448, B-1040) | | | | | | | | | ['Button9', 'Close3', 'CloseButton3'] | | | | | | | | | child_window(title="Close", control_type="Button") | | | | | | | | | | | | Button - 'New Tab' (L1448, T-1071, R1482, B-1040) | | | | | | ['New Tab', 'New TabButton', 'Button10'] | | | | | | child_window(title="New Tab", control_type="Button") | | | | | | | | | | | | Pane - '' (L1482, T-1071, R1736, B-1040) | | | | | | ['Pane10'] | | | | | | | | | | Toolbar - '' (L961, T-1041, R1919, B-1005) | | | | | ['ToolbarEdit bookmark for this tab', 'ToolbarNot secure', 'ToolbarTESTING', 'ToolbarWallet', 'Toolbar', 'ToolbarForward', 'ToolbarBrave', 'ToolbarReload', 'ToolbarAddress and search bar', 'Toolbar0', 'Toolbar1'] | | | | | | | | | | | | Button - 'Back' (L969, T-1037, R997, B-1009) | | | | | | ['Back', 'BackButton', 'Button11'] | | | | | | child_window(title="Back", control_type="Button") | | | | | | | | | | | | Button - 'Forward' (L1001, T-1037, R1029, B-1009) | | | | | | ['Forward', 'ForwardButton', 'Button12'] | | | | | | child_window(title="Forward", control_type="Button") | | | | | | | | | | | | Button - 'Reload' (L1033, T-1037, R1061, B-1009) | | | | | | ['ReloadButton', 'Reload', 'Button13'] | | | | | | child_window(title="Reload", control_type="Button") | | | | | | | | | | | | Button - 'Edit bookmark for this tab' (L1123, T-1037, R1151, B-1009) | | | | | | ['Edit bookmark for this tabButton', 'Edit bookmark for this tab', 'Button14'] | | | | | | child_window(title="Edit bookmark for this tab", control_type="Button") | | | | | | | | | | | | MenuItem - 'Not secure' (L1161, T-1035, R1278, B-1011) | | | | | | ['Not secureMenuItem', 'Not secure', 'MenuItem3'] | | | | | | child_window(title="Not secure", control_type="MenuItem") | | | | | | | | | | | | Edit - 'Address and search bar' (L1278, T-1035, R1502, B-1011) | | | | | | ['Edit3'] | | | | | | child_window(title="Address and search bar", control_type="Edit") | | | | | | | | | | | | Pane - '' (L0, T0, R0, B0) | | | | | | ['Pane11'] | | | | | | | | | | | | Pane - '' (L1504, T-1037, R1579, B-1009) | | | | | | ['Pane12'] | | | | | | | | | | | | | | Separator - 'Separator' (L1504, T-1031, R1511, B-1015) | | | | | | | ['SeparatorSeparator', 'Separator'] | | | | | | | child_window(title="Separator", control_type="Separator") | | | | | | | | | | | | | | MenuItem - 'Brave Shields' (L1511, T-1035, R1545, B-1011) | | | | | | | ['Brave ShieldsMenuItem', 'MenuItem4', 'Brave Shields'] | | | | | | | child_window(title="Brave Shields", control_type="MenuItem") | | | | | | | | | | | | | | Button - 'Brave Rewards' (L1545, T-1035, R1579, B-1011) | | | | | | | ['Brave Rewards', 'Brave RewardsButton', 'Button15'] | | | | | | | child_window(title="Brave Rewards", control_type="Button") | | | | | | | | | | | | Pane - '' (L1623, T-1037, R1811, B-1009) | | | | | | ['Pane13'] | | | | | | | | | | | | | | MenuItem - 'Bitdefender Anti-tracker\nHas access to this site' (L1623, T-1037, R1651, B-1009) | | | | | | | ['Bitdefender Anti-tracker\nHas access to this siteMenuItem', 'Bitdefender Anti-tracker\nHas access to this site', 'MenuItem5'] | | | | | | | child_window(title="Bitdefender Anti-tracker\nHas access to this site", control_type="MenuItem") | | | | | | | | | | | | | | MenuItem - 'Bitdefender Wallet is on\nHas access to this site' (L1655, T-1037, R1683, B-1009) | | | | | | | ['Bitdefender Wallet is on\nHas access to this siteMenuItem', 'MenuItem6', 'Bitdefender Wallet is on\nHas access to this site'] | | | | | | | child_window(title="Bitdefender Wallet is on\nHas access to this site", control_type="MenuItem") | | | | | | | | | | | | | | MenuItem - 'Microsoft Power Automate\nHas access to this site' (L1687, T-1037, R1715, B-1009) | | | | | | | ['Microsoft Power Automate\nHas access to this site', 'Microsoft Power Automate\nHas access to this siteMenuItem', 'MenuItem7'] | | | | | | | child_window(title="Microsoft Power Automate\nHas access to this site", control_type="MenuItem") | | | | | | | | | | | | | | MenuItem - 'Session Buddy' (L1719, T-1037, R1747, B-1009) | | | | | | | ['Session BuddyMenuItem', 'Session Buddy', 'MenuItem8'] | | | | | | | child_window(title="Session Buddy", control_type="MenuItem") | | | | | | | | | | | | | | MenuItem - 'Selenium IDE\nHas access to this site' (L1751, T-1037, R1779, B-1009) | | | | | | | ['Selenium IDE\nHas access to this site', 'Selenium IDE\nHas access to this siteMenuItem', 'MenuItem9'] | | | | | | | child_window(title="Selenium IDE\nHas access to this site", control_type="MenuItem") | | | | | | | | | | | | | | MenuItem - 'Extensions' (L1783, T-1037, R1811, B-1009) | | | | | | | ['MenuItem10', 'ExtensionsMenuItem', 'Extensions'] | | | | | | | child_window(title="Extensions", control_type="MenuItem") | | | | | | | | | | | | MenuItem - 'Wallet' (L1815, T-1039, R1847, B-1007) | | | | | | ['Wallet', 'WalletMenuItem', 'MenuItem11'] | | | | | | child_window(title="Wallet", control_type="MenuItem") | | | | | | | | | | | | Button - 'TESTING' (L1851, T-1037, R1879, B-1009) | | | | | | ['TESTING3', 'Button16', 'TESTINGButton'] | | | | | | child_window(title="TESTING", control_type="Button") | | | | | | | | | | | | MenuItem - 'Brave' (L1883, T-1037, R1911, B-1009) | | | | | | ['Brave2', 'BraveMenuItem', 'MenuItem12'] | | | | | | child_window(title="Brave", control_type="MenuItem") | | | | | | | | | | Pane - '' (L961, T-973, R1919, B-972) | | | | | ['Pane14'] | | | | | | | | | | Toolbar - 'Bookmarks' (L961, T-1005, R1919, B-973) | | | | | ['Toolbar2', 'Bookmarks', 'BookmarksToolbar'] | | | | | child_window(title="Bookmarks", control_type="ToolBar") | | | | | | | | | | | | Button - 'Download Website' (L969, T-1005, R1105, B-977) | | | | | | ['Download Website', 'Download WebsiteButton', 'Button17'] | | | | | | child_window(title="Download Website", control_type="Button") | | | | | | | | | | | | Button - 'INVENTORY' (L1109, T-1005, R1209, B-977) | | | | | | ['INVENTORY', 'INVENTORYButton', 'Button18'] | | | | | | child_window(title="INVENTORY", control_type="Button") | | | | | | | | Pane - '' (L961, T-972, R1919, B-31) | | | | ['Pane15', 'Username or Email AddressPane4'] | | | | | | | | | | Pane - '' (L0, T0, R0, B0) | | | | | ['Pane16'] | | | | | | | | | | Pane - '' (L961, T-972, R1919, B-31) | | | | | ['Pane17', 'Username or Email AddressPane5'] | | | | | | | | Pane - '' (L0, T0, R0, B0) | | | | ['Pane18'] | | | | | | | | Pane - '' (L0, T0, R0, B0) | | | | ['Pane19'] CODE from pywinauto import application as appl from pywinauto import findwindows as fw def startApp(app_path, backend="win32"): #print(app_handle) app = appl.Application(backend=backend) try: app.connect(path=app_path) except (WindowNotFoundError, ProcessNotFoundError): app.start(app_path) return app app = startApp(bravePath, backend="uia") time.sleep(1) winElem = fw.find_elements(title_re=".*TESTING.*", top_level_only=False) if winElem: handle = winElem[0].handle procId = winElem[0].process_id app = appl.Application(backend='uia') app = app.connect(path=bravePath, process=procId) dlg = app.window(title_re="TESTING") tabs = dlg.Pane9.iter_descendants() # <generator object BaseWrapper.iter_descendants at 0x0000024AC8FD0580>
You can try this code with Chrome: import pywinauto desktop = pywinauto.Desktop(backend="uia") window = desktop.windows(title_re=".* Google Chrome$", control_type="Pane")[0] wrapper_list = window.descendants(control_type="TabItem") for wrapper in wrapper_list: print(wrapper.window_text()) It prints the name of all tabs then you just have to get the url of each tab: import pywinauto desktop = pywinauto.Desktop(backend="uia") window = desktop.windows(title_re=".* Google Chrome$", control_type="Pane")[0] wrapper_list = window.descendants(control_type="TabItem") for wrapper in wrapper_list: wrapper.click_input() wrapper_url = window.descendants(title="Address and search bar", control_type="Edit")[0] print(wrapper_url.get_value())
Control Windows app (HMA VPN) using PyWinAuto
I am trying to write Python code to request my vpn software to connect / disconnect upon certain conditions. I use HMA VPN and am running on Windows 10. Python 3.9.5. The PyWinAuto module would appear to have the required functionality, but I cannot get it to work correctly. I'm sure it's my coding, not the module itself... ;) I'm fairly sure I'm referring to the control incorrectly when I call it with the click() method, but can anyone suggest the correct approach, given the dump_tree that I have included? (I have tried tens of variations based based on the code snippets in the Getting Started guide, but no joy). I'm looking to be able to toggle Button4 in GroupBox2, which is named either "Connect" or "Disconnect", depending on the current state of the VPN. I also want to be able to click Button5, "Change IP Address", but once I figure out one button, the other should be easy. Any thoughts where I am going wrong? My code snippet is as follows: from pywinauto import Desktop, Application Desktop(backend='uia').HMAVPN.dump_tree() app = Application().start('C:\Program Files\Privax\HMA VPN\Vpn.exe', timeout=5) dlg_spec = app.window(title='HMA VPN') dlg_spec.AvastChromiumWindow.Pane2.Document.GroupBox2.Button4.click() The resulting output is as follows: Control Identifiers: Dialog - 'HMA VPN' (L-149, T68, R551, B638) ['HMA VPNDialog', 'HMA VPN', 'Dialog'] child_window(title="HMA VPN", control_type="Window") | | Pane - 'AvastChromiumWindow' (L-149, T68, R551, B638) | ['Pane', 'AvastChromiumWindowPane', 'AvastChromiumWindow', 'Pane0', 'Pane1'] | child_window(title="AvastChromiumWindow", control_type="Pane") | | | | Pane - '' (L-149, T68, R551, B638) | | ['Pane2', '\ue01bPane', '\ue01bPane0', '\ue01bPane1'] | | | | | | Document - ' Original IP 91.90.253.244 New IP 80.255.5.198 Original IP 91.90.253.244 Location Germany, Berlin ' (L-149, T68, R551, B638) | | | ['\ue01b \ue014 \ue007 Original IP \xa0 91.90.253.244 New IP \xa0 80.255.5.198 \ue019 Original IP \xa0 91.90.253.244 \xa0 Location Germany, Berlin \ue005 Document', 'Document', '\ue01b \ue014 \ue007 Original IP \xa0 91.90.253.244 New IP \xa0 80.255.5.198 \ue019 Original IP \xa0 91.90.253.244 \xa0 Location Germany, Berlin \ue005 '] | | | child_window(title=" Original IP 91.90.253.244 New IP 80.255.5.198 Original IP 91.90.253.244 Location Germany, Berlin ", auto_id="7211296", control_type="Document") | | | | | | | | GroupBox - '' (L-149, T68, R551, B104) | | | | ['\ue01bGroupBox', 'GroupBox', '\ue01bGroupBox0', '\ue01bGroupBox1', 'GroupBox0', 'GroupBox1'] | | | | | | | | | | Button - 'Preferences' (L-134, T76, R-114, B96) | | | | | ['PreferencesButton', 'Preferences', 'Button', 'Button0', 'Button1'] | | | | | child_window(title="Preferences", auto_id="hma_title__preferences", control_type="Button") | | | | | | | | | | | | Static - '' (L-134, T76, R-114, B96) | | | | | | ['Static', '\ue01b', '\ue01bStatic', 'Static0', 'Static1'] | | | | | | child_window(title="", control_type="Text") | | | | | | | | | | Button - 'Minimize' (L486, T76, R506, B96) | | | | | ['Minimize', 'Button2', 'MinimizeButton'] | | | | | child_window(title="Minimize", control_type="Button") | | | | | | | | | | | | Static - '' (L486, T76, R506, B96) | | | | | | ['\ue014Static', 'Static2', '\ue014'] | | | | | | child_window(title="", control_type="Text") | | | | | | | | | | Button - 'Close' (L516, T76, R536, B96) | | | | | ['Close', 'Button3', 'CloseButton'] | | | | | child_window(title="Close", control_type="Button") | | | | | | | | | | | | Static - '' (L516, T76, R536, B96) | | | | | | ['Static3', '\ue007', '\ue007Static'] | | | | | | child_window(title="", control_type="Text") | | | | | | | | GroupBox - '' (L-149, T68, R551, B638) | | | | ['\ue01bGroupBox2', 'GroupBox2'] | | | | | | | | | | Image - '' (L111, T120, R291, B300) | | | | | ['\ue01bImage', 'Image'] | | | | | | | | | | Button - 'Disconnect' (L126, T323, R276, B383) | | | | | ['Button4', 'DisconnectButton', 'Disconnect'] | | | | | child_window(title="Disconnect", auto_id="dashboard_switch", control_type="Button") | | | | | | | | | | Static - 'Original IP' (L68, T414, R135, B430) | | | | | ['Original IPStatic', 'Static4', 'Original IP', 'Original IPStatic0', 'Original IPStatic1', 'Original IP0', 'Original IP1'] | | | | | child_window(title="Original IP", control_type="Text") | | | | | | | | | | Static - ' ' (L164, T412, R168, B427) | | | | | ['Static5', '\xa0Static', '\xa0', '\xa0Static0', '\xa0Static1', '\xa00', '\xa01'] | | | | | child_window(title=" ", control_type="Text") | | | | | | | | | | Static - '91.90.253.244' (L184, T414, R266, B429) | | | | | ['Static6', '91.90.253.244Static', '91.90.253.244', '91.90.253.244Static0', '91.90.253.244Static1', '91.90.253.2440', '91.90.253.2441'] | | | | | child_window(title="91.90.253.244", control_type="Text") | | | | | | | | | | Static - 'New IP' (L68, T442, R113, B458) | | | | | ['New IP', 'Static7', 'New IPStatic'] | | | | | child_window(title="New IP", control_type="Text") | | | | | | | | | | Static - ' ' (L164, T440, R168, B455) | | | | | ['Static8', '\xa0Static2', '\xa02'] | | | | | child_window(title=" ", control_type="Text") | | | | | | | | | | Static - '80.255.5.198' (L184, T442, R258, B457) | | | | | ['Static9', '80.255.5.198', '80.255.5.198Static'] | | | | | child_window(title="80.255.5.198", control_type="Text") | | | | | | | | | | Button - 'Change IP Address' (L294, T416, R334, B456) | | | | | ['Change IP AddressButton', 'Button5', 'Change IP Address'] | | | | | child_window(title="Change IP Address", auto_id="ip_change", control_type="Button") | | | | | | | | | | Static - 'Original IP' (L95, T428, R162, B444) | | | | | ['Original IPStatic2', 'Static10', 'Original IP2'] | | | | | child_window(title="Original IP", control_type="Text") | | | | | | | | | | Static - ' ' (L191, T426, R196, B441) | | | | | ['Static11', '\xa0Static3', '\xa03'] | | | | | child_window(title=" ", control_type="Text") | | | | | | | | | | Static - '91.90.253.244' (L211, T428, R293, B443) | | | | | ['Static12', '91.90.253.244Static2', '91.90.253.2442'] | | | | | child_window(title="91.90.253.244", control_type="Text") | | | | | | | | | | Button - 'Location Germany, Berlin' (L31, T489, R371, B569) | | | | | ['Button6', 'Location Germany, BerlinButton', 'Location Germany, Berlin'] | | | | | child_window(title="Location Germany, Berlin", auto_id="dashboard_chooseLocation", control_type="Button") | | | | | | | | | | | | Static - ' ' (L51, T507, R55, B522) | | | | | | ['Static13', '\xa0Static4', '\xa04'] | | | | | | child_window(title=" ", control_type="Text") | | | | | | | | | | | | Static - 'Location' (L111, T511, R164, B526) | | | | | | ['Static14', 'Location', 'LocationStatic'] | | | | | | child_window(title="Location", control_type="Text") | | | | | | | | | | | | Static - 'Germany, Berlin' (L111, T529, R219, B546) | | | | | | ['Static15', 'Germany, Berlin', 'Germany, BerlinStatic'] | | | | | | child_window(title="Germany, Berlin", control_type="Text") | | | | | | | | | | | | Static - '' (L331, T519, R351, B539) | | | | | | ['Static16', '\ue005', '\ue005Static'] | | | | | | child_window(title="", control_type="Text") | | | | | | | | | | Button - 'More' (L420, T107, R528, B137) | | | | | ['More', 'Button7', 'MoreButton'] | | | | | child_window(title="More", control_type="Button") | | | | | | Pane - '' (L-149, T68, R551, B638) | | | ['Pane3', '\ue01bPane2'] Traceback (most recent call last): File "C:\Users\db533\VirtualBox VMs\pycharm-gunabot\venv\lib\site-packages\pywinauto\application.py", line 250, in __resolve_control ctrl = wait_until_passes( File "C:\Users\db533\VirtualBox VMs\pycharm-gunabot\venv\lib\site-packages\pywinauto\timings.py", line 458, in wait_until_passes raise err pywinauto.timings.TimeoutError During handling of the above exception, another exception occurred: Traceback (most recent call last): File "C:\Users\db533\PycharmProjects\GunaBot\hma_control.py", line 19, in <module> dlg_spec.AvastChromiumWindow.Pane2.Document.GroupBox2.Button4.click() File "C:\Users\db533\VirtualBox VMs\pycharm-gunabot\venv\lib\site-packages\pywinauto\application.py", line 379, in __getattribute__ ctrls = self.__resolve_control(self.criteria) File "C:\Users\db533\VirtualBox VMs\pycharm-gunabot\venv\lib\site-packages\pywinauto\application.py", line 261, in __resolve_control raise e.original_exception File "C:\Users\db533\VirtualBox VMs\pycharm-gunabot\venv\lib\site-packages\pywinauto\timings.py", line 436, in wait_until_passes func_val = func(*args, **kwargs) File "C:\Users\db533\VirtualBox VMs\pycharm-gunabot\venv\lib\site-packages\pywinauto\application.py", line 203, in __get_ctrl dialog = self.backend.generic_wrapper_class(findwindows.find_element(**criteria[0])) File "C:\Users\db533\VirtualBox VMs\pycharm-gunabot\venv\lib\site-packages\pywinauto\findwindows.py", line 87, in find_element raise ElementNotFoundError(kwargs) pywinauto.findwindows.ElementNotFoundError: {'title': 'HMA VPN', 'backend': 'win32', 'process': 40580} Process finished with exit code 1
Cracked it! The following code let's me toggle the Connect / Disconnect button and change the IP. from pywinauto import Desktop,Application vpn_app = Application(backend="uia").start('C:\Program Files\Privax\HMA VPN\Vpn.exe') dialog=Desktop(backend="uia").HMA panel0=dialog.Pane # Command to connect / disconnect the VPN: connect_button.click() connect_button=panel0.ConnectButton # Command to change the IP address: changeIP.click() changeIP=panel0.Button5 # Check VPN state: # 0 if disconnected # 1 if connected print(connect_button.get_toggle_state()) # Command to connect / disconnect the VPN: connect_button.click() connect_button=panel0.ConnectButton connect_button.click() # Command to change the IP address: changeIP.click() changeIP=panel0.Button5 changeIP.click() # Check VPN state: # 0 if disconnected # 1 if connected print(connect_button.get_toggle_state())
Web scraping: how to iterate over all the pages from a url and store the result in a table
I am not able to resolve this loop. I want to iterate over all pages from the URL and put all the names in a table. There are 102 pages. Thank you in advance. [from bs4 import BeautifulSoup import re import requests url = "https://www.prokerala.com/kids/baby-names/hindu/" r = requests.get(url) soup = BeautifulSoup(r.content, "html.parser") next_page = soup.find('a', {'class': 'next'}).get('href') l=(f'{next_page}') new_url=url+l link=soup.find('span', {'class' : \['a name-details girl-names', 'a name-details boy-names'\] }) print("href='>%s'>%s</a>" % (link.get("href"), link.text)) while True: r = requests.get(new_url) soup = BeautifulSoup(r.content, "html.parser") next_page = soup.find('a', {'class': 'next'}).get('href') link=soup.find('span', {'class' : \['a name-details girl-names', 'a name-details boy-names'\] }) print("href='>%s'>%s</a>" % (link.get("href"), link.text)) l=(f'{next_page}') new_url=url+l if BeautifulSoup(r.content, "html.parser")is True: break][1] [1]: https://i.stack.imgur.com/SgM4I.png
from bs4 import BeautifulSoup import requests import re from prettytable import PrettyTable def main(url): with requests.Session() as req: p = PrettyTable() p.field_names = ['Name', 'Url'] for item in range(1, 3): r = req.get(url.format(item)) soup = BeautifulSoup(r.content, 'html.parser') for item in soup.findAll("span", class_=re.compile("a name")): p.add_row([item.a.text, f'{url[:25]}{item.a.get("href")}']) print(p) main("https://www.prokerala.com/kids/baby-names/hindu/page-{}.html") Output: +---------------+--------------------------------------------------------------------+ | Name | Url | +---------------+--------------------------------------------------------------------+ | Aabha | https://www.prokerala.com/kids/baby-names/aabha-13597.html | | Aabheer | https://www.prokerala.com/kids/baby-names/aabheer-2.html | | Aachal | https://www.prokerala.com/kids/baby-names/aachal-20815.html | | Aadarsh | https://www.prokerala.com/kids/baby-names/aadarsh-3.html | | Aadarshini | https://www.prokerala.com/kids/baby-names/aadarshini-20997.html | | Aadav | https://www.prokerala.com/kids/baby-names/aadav-21329.html | | Aadavan | https://www.prokerala.com/kids/baby-names/aadavan-19505.html | | Aadesh | https://www.prokerala.com/kids/baby-names/aadesh-4.html | | Aadhan | https://www.prokerala.com/kids/baby-names/aadhan-5.html | | Aadharsha | https://www.prokerala.com/kids/baby-names/aadharsha-20812.html | | Aadhik | https://www.prokerala.com/kids/baby-names/aadhik-19726.html | | Aadhikesav | https://www.prokerala.com/kids/baby-names/aadhikesav-21003.html | | Aadhinath | https://www.prokerala.com/kids/baby-names/aadhinath-21392.html | | Aadhira | https://www.prokerala.com/kids/baby-names/aadhira-6.html | | Aadhira | https://www.prokerala.com/kids/baby-names/aadhira-20603.html | | Aadhith | https://www.prokerala.com/kids/baby-names/aadhith-21626.html | | Aadhriti | https://www.prokerala.com/kids/baby-names/aadhriti-20601.html | | Aadhunik | https://www.prokerala.com/kids/baby-names/aadhunik-21198.html | | Aadhvitha | https://www.prokerala.com/kids/baby-names/aadhvitha-20571.html | | Aadhya | https://www.prokerala.com/kids/baby-names/aadhya-21327.html | | Aadi | https://www.prokerala.com/kids/baby-names/aadi-7.html | | Aadidev | https://www.prokerala.com/kids/baby-names/aadidev-8.html | | Aadilakshmi | https://www.prokerala.com/kids/baby-names/aadilakshmi-20995.html | | Aadimoolan | https://www.prokerala.com/kids/baby-names/aadimoolan-20920.html | | Aadinadh | https://www.prokerala.com/kids/baby-names/aadinadh-20614.html | | Aadinath | https://www.prokerala.com/kids/baby-names/aadinath-10.html | | Aadinathan | https://www.prokerala.com/kids/baby-names/aadinathan-24838.html | | Aadipta | https://www.prokerala.com/kids/baby-names/aadipta-20922.html | | Aadir | https://www.prokerala.com/kids/baby-names/aadir-11.html | | Aadish | https://www.prokerala.com/kids/baby-names/aadish-20945.html | | Aadishree | https://www.prokerala.com/kids/baby-names/aadishree-21389.html | | Aadit | https://www.prokerala.com/kids/baby-names/aadit-12.html | | Aaditey | https://www.prokerala.com/kids/baby-names/aaditey-20921.html | | Aaditeya | https://www.prokerala.com/kids/baby-names/aaditeya-13.html | | Aaditya | https://www.prokerala.com/kids/baby-names/aaditya-22619.html | | Aadrika | https://www.prokerala.com/kids/baby-names/aadrika-20925.html | | Aadvay | https://www.prokerala.com/kids/baby-names/aadvay-22288.html | | Aadvik | https://www.prokerala.com/kids/baby-names/aadvik-19508.html | | Aadya | https://www.prokerala.com/kids/baby-names/aadya-19557.html | | Aadyasha | https://www.prokerala.com/kids/baby-names/aadyasha-20570.html | | Aafreen | https://www.prokerala.com/kids/baby-names/aafreen-19244.html | | Aagam | https://www.prokerala.com/kids/baby-names/aagam-16.html | | Aaghosh | https://www.prokerala.com/kids/baby-names/aaghosh-22289.html | | Aagney | https://www.prokerala.com/kids/baby-names/aagney-17.html | | Aagneya | https://www.prokerala.com/kids/baby-names/aagneya-18.html | | Aahan | https://www.prokerala.com/kids/baby-names/aahan-19.html | | Aahana | https://www.prokerala.com/kids/baby-names/aahana-21194.html | | Aahish | https://www.prokerala.com/kids/baby-names/aahish-22290.html | | Aahlaad | https://www.prokerala.com/kids/baby-names/aahlaad-21.html | | Aahva | https://www.prokerala.com/kids/baby-names/aahva-22.html | | Aahvan | https://www.prokerala.com/kids/baby-names/aahvan-23857.html | | Aakaar | https://www.prokerala.com/kids/baby-names/aakaar-23.html | | Aakaash | https://www.prokerala.com/kids/baby-names/aakaash-24.html | | Aakanksha | https://www.prokerala.com/kids/baby-names/aakanksha-19223.html | | Aakar | https://www.prokerala.com/kids/baby-names/aakar-25.html | | Aakarshan | https://www.prokerala.com/kids/baby-names/aakarshan-26.html | | Aakash | https://www.prokerala.com/kids/baby-names/aakash-19650.html | | Aalap | https://www.prokerala.com/kids/baby-names/aalap-27.html | | Aalok | https://www.prokerala.com/kids/baby-names/aalok-28.html | | Aamil | https://www.prokerala.com/kids/baby-names/aamil-17109.html | | Aamod | https://www.prokerala.com/kids/baby-names/aamod-30.html | | Aanan | https://www.prokerala.com/kids/baby-names/aanan-23674.html | | Aanand | https://www.prokerala.com/kids/baby-names/aanand-31.html | | Aanandhi | https://www.prokerala.com/kids/baby-names/aanandhi-19971.html | | Aanandswarup | https://www.prokerala.com/kids/baby-names/aanandswarup-32.html | | Aananthan | https://www.prokerala.com/kids/baby-names/aananthan-26697.html | | Aanav | https://www.prokerala.com/kids/baby-names/aanav-19506.html | | Aanchal | https://www.prokerala.com/kids/baby-names/aanchal-26403.html | | Aandaleeb | https://www.prokerala.com/kids/baby-names/aandaleeb-33.html | | Aanjaneya | https://www.prokerala.com/kids/baby-names/aanjaneya-34.html | | Aanjay | https://www.prokerala.com/kids/baby-names/aanjay-23679.html | | Aapt | https://www.prokerala.com/kids/baby-names/aapt-35.html | | Aaraadhak | https://www.prokerala.com/kids/baby-names/aaraadhak-37.html | | Aaradhya | https://www.prokerala.com/kids/baby-names/aaradhya-19272.html | | Aaranyan | https://www.prokerala.com/kids/baby-names/aaranyan-23680.html | | Aarathi | https://www.prokerala.com/kids/baby-names/aarathi-24839.html | | Aarav | https://www.prokerala.com/kids/baby-names/aarav-38.html | | Aardik | https://www.prokerala.com/kids/baby-names/aardik-26698.html | | Aarhant | https://www.prokerala.com/kids/baby-names/aarhant-39.html | | Aarin | https://www.prokerala.com/kids/baby-names/aarin-19496.html | | Aarit | https://www.prokerala.com/kids/baby-names/aarit-41.html | | Aariv | https://www.prokerala.com/kids/baby-names/aariv-19507.html | | Aarna | https://www.prokerala.com/kids/baby-names/aarna-24840.html | | Aarnav | https://www.prokerala.com/kids/baby-names/aarnav-44.html | | Aarodeep | https://www.prokerala.com/kids/baby-names/aarodeep-26700.html | | Aaroha | https://www.prokerala.com/kids/baby-names/aaroha-21497.html | | Aaromal | https://www.prokerala.com/kids/baby-names/aaromal-26701.html | | Aarpit | https://www.prokerala.com/kids/baby-names/aarpit-46.html | | Aarsh | https://www.prokerala.com/kids/baby-names/aarsh-47.html | | Aarshabh | https://www.prokerala.com/kids/baby-names/aarshabh-23864.html | | Aarth | https://www.prokerala.com/kids/baby-names/aarth-48.html | | Aarthi | https://www.prokerala.com/kids/baby-names/aarthi-24320.html | | Aarti | https://www.prokerala.com/kids/baby-names/aarti-24228.html | | Aarul | https://www.prokerala.com/kids/baby-names/aarul-19501.html | | Aarunya | https://www.prokerala.com/kids/baby-names/aarunya-21502.html | | Aarush | https://www.prokerala.com/kids/baby-names/aarush-49.html | | Aarushi | https://www.prokerala.com/kids/baby-names/aarushi-50.html | | Aarya | https://www.prokerala.com/kids/baby-names/aarya-19111.html | | Aaryah | https://www.prokerala.com/kids/baby-names/aaryah-13617.html | | Aaryan | https://www.prokerala.com/kids/baby-names/aaryan-51.html | | Aaryana | https://www.prokerala.com/kids/baby-names/aaryana-13618.html | | Aaryanna | https://www.prokerala.com/kids/baby-names/aaryanna-13619.html | | Aashadhar | https://www.prokerala.com/kids/baby-names/aashadhar-21503.html | | Aashank | https://www.prokerala.com/kids/baby-names/aashank-53.html | | Aashay | https://www.prokerala.com/kids/baby-names/aashay-54.html | | Aashi | https://www.prokerala.com/kids/baby-names/aashi-24841.html | | Aashirya | https://www.prokerala.com/kids/baby-names/aashirya-19779.html | | Aashish | https://www.prokerala.com/kids/baby-names/aashish-55.html | | Aashman | https://www.prokerala.com/kids/baby-names/aashman-56.html | | Aashna | https://www.prokerala.com/kids/baby-names/aashna-19991.html | | Aashutosh | https://www.prokerala.com/kids/baby-names/aashutosh-57.html | | Aastha | https://www.prokerala.com/kids/baby-names/aastha-19567.html | | Aastik | https://www.prokerala.com/kids/baby-names/aastik-60.html | | Aathira | https://www.prokerala.com/kids/baby-names/aathira-24842.html | | Aatish | https://www.prokerala.com/kids/baby-names/aatish-62.html | | Aatmaj | https://www.prokerala.com/kids/baby-names/aatmaj-63.html | | Aatreya | https://www.prokerala.com/kids/baby-names/aatreya-64.html | | Aayan | https://www.prokerala.com/kids/baby-names/aayan-65.html | | Aayu | https://www.prokerala.com/kids/baby-names/aayu-66.html | | Aayush | https://www.prokerala.com/kids/baby-names/aayush-24843.html | | Aayushi | https://www.prokerala.com/kids/baby-names/aayushi-26998.html | | Aayushmaan | https://www.prokerala.com/kids/baby-names/aayushmaan-67.html | | Abadhya | https://www.prokerala.com/kids/baby-names/abadhya-19727.html | | Abeesh | https://www.prokerala.com/kids/baby-names/abeesh-19724.html | | Abeesht | https://www.prokerala.com/kids/baby-names/abeesht-20923.html | | Aben | https://www.prokerala.com/kids/baby-names/aben-19257.html | | Abha | https://www.prokerala.com/kids/baby-names/abha-7340.html | | Abhaiveer | https://www.prokerala.com/kids/baby-names/abhaiveer-23649.html | | Abhanja | https://www.prokerala.com/kids/baby-names/abhanja-23670.html | | Abhas | https://www.prokerala.com/kids/baby-names/abhas-19723.html | | Abhat | https://www.prokerala.com/kids/baby-names/abhat-19722.html | | Abhati | https://www.prokerala.com/kids/baby-names/abhati-18373.html | | Abhay | https://www.prokerala.com/kids/baby-names/abhay-154.html | | Abhaya | https://www.prokerala.com/kids/baby-names/abhaya-7341.html | | Abhayan | https://www.prokerala.com/kids/baby-names/abhayan-22297.html | | Abhayananda | https://www.prokerala.com/kids/baby-names/abhayananda-18027.html | | Abhayaprada | https://www.prokerala.com/kids/baby-names/abhayaprada-18028.html | | Abhayd | https://www.prokerala.com/kids/baby-names/abhayd-22295.html | | Abhayd | https://www.prokerala.com/kids/baby-names/abhayd-22296.html | | Abhaysimha | https://www.prokerala.com/kids/baby-names/abhaysimha-23650.html | | Abheek | https://www.prokerala.com/kids/baby-names/abheek-155.html | | Abhey | https://www.prokerala.com/kids/baby-names/abhey-22292.html | | Abhi | https://www.prokerala.com/kids/baby-names/abhi-156.html | | Abhibhava | https://www.prokerala.com/kids/baby-names/abhibhava-18029.html | | Abhicandra | https://www.prokerala.com/kids/baby-names/abhicandra-18030.html | | Abhidha | https://www.prokerala.com/kids/baby-names/abhidha-18374.html | | Abhidhya | https://www.prokerala.com/kids/baby-names/abhidhya-18375.html | | Abhidi | https://www.prokerala.com/kids/baby-names/abhidi-18031.html | | Abhigita | https://www.prokerala.com/kids/baby-names/abhigita-23855.html | | Abhigna | https://www.prokerala.com/kids/baby-names/abhigna-24844.html | | Abhigyaan | https://www.prokerala.com/kids/baby-names/abhigyaan-23671.html | | Abhihita | https://www.prokerala.com/kids/baby-names/abhihita-18032.html | | Abhijaat | https://www.prokerala.com/kids/baby-names/abhijaat-157.html | | Abhijat | https://www.prokerala.com/kids/baby-names/abhijat-18787.html | | Abhijay | https://www.prokerala.com/kids/baby-names/abhijay-158.html | | Abhijaya | https://www.prokerala.com/kids/baby-names/abhijaya-18033.html | | Abhijeet | https://www.prokerala.com/kids/baby-names/abhijeet-17122.html | | Abhiji | https://www.prokerala.com/kids/baby-names/abhiji-25946.html | | Abhijit | https://www.prokerala.com/kids/baby-names/abhijit-159.html | | Abhijith | https://www.prokerala.com/kids/baby-names/abhijith-23839.html | | Abhijun | https://www.prokerala.com/kids/baby-names/abhijun-160.html | | Abhijvala | https://www.prokerala.com/kids/baby-names/abhijvala-18034.html | | Abhik | https://www.prokerala.com/kids/baby-names/abhik-161.html | | Abhikama | https://www.prokerala.com/kids/baby-names/abhikama-19719.html | | Abhikansh | https://www.prokerala.com/kids/baby-names/abhikansh-19720.html | | Abhilasa | https://www.prokerala.com/kids/baby-names/abhilasa-18376.html | | Abhilash | https://www.prokerala.com/kids/baby-names/abhilash-162.html | | Abhilasha | https://www.prokerala.com/kids/baby-names/abhilasha-7342.html | | Abhim | https://www.prokerala.com/kids/baby-names/abhim-19721.html | | Abhimand | https://www.prokerala.com/kids/baby-names/abhimand-18035.html | | Abhimani | https://www.prokerala.com/kids/baby-names/abhimani-18036.html | | Abhimanyu | https://www.prokerala.com/kids/baby-names/abhimanyu-163.html | | Abhimanyusuta | https://www.prokerala.com/kids/baby-names/abhimanyusuta-18037.html | | Abhimoda | https://www.prokerala.com/kids/baby-names/abhimoda-18038.html | | Abhin | https://www.prokerala.com/kids/baby-names/abhin-164.html | | Abhinabhas | https://www.prokerala.com/kids/baby-names/abhinabhas-18039.html | | Abhinand | https://www.prokerala.com/kids/baby-names/abhinand-23672.html | | Abhinanda | https://www.prokerala.com/kids/baby-names/abhinanda-18040.html | | Abhinandan | https://www.prokerala.com/kids/baby-names/abhinandan-165.html | | Abhinandana | https://www.prokerala.com/kids/baby-names/abhinandana-18788.html | | Abhinatha | https://www.prokerala.com/kids/baby-names/abhinatha-18041.html | | Abhinav | https://www.prokerala.com/kids/baby-names/abhinav-166.html | | Abhinava | https://www.prokerala.com/kids/baby-names/abhinava-18042.html | | Abhinavin | https://www.prokerala.com/kids/baby-names/abhinavin-19729.html | | Abhinay | https://www.prokerala.com/kids/baby-names/abhinay-168.html | | Abhinaya | https://www.prokerala.com/kids/baby-names/abhinaya-23651.html | | Abhineet | https://www.prokerala.com/kids/baby-names/abhineet-169.html | | Abhinit | https://www.prokerala.com/kids/baby-names/abhinit-170.html | | Abhinithi | https://www.prokerala.com/kids/baby-names/abhinithi-18377.html | | Abhinivesh | https://www.prokerala.com/kids/baby-names/abhinivesh-171.html | | Abhiprithi | https://www.prokerala.com/kids/baby-names/abhiprithi-18378.html | | Abhir | https://www.prokerala.com/kids/baby-names/abhir-172.html | | Abhiraam | https://www.prokerala.com/kids/baby-names/abhiraam-173.html | | Abhiraj | https://www.prokerala.com/kids/baby-names/abhiraj-174.html | | Abhiraksh | https://www.prokerala.com/kids/baby-names/abhiraksh-19733.html | | Abhirakshit | https://www.prokerala.com/kids/baby-names/abhirakshit-19732.html | | Abhiram | https://www.prokerala.com/kids/baby-names/abhiram-19728.html | | Abhirami | https://www.prokerala.com/kids/baby-names/abhirami-24745.html | | Abhirath | https://www.prokerala.com/kids/baby-names/abhirath-175.html | | Abhirathi | https://www.prokerala.com/kids/baby-names/abhirathi-18379.html | +---------------+--------------------------------------------------------------------+