SlideShare une entreprise Scribd logo
1  sur  29
Télécharger pour lire hors ligne
BUILDING CLIS THAT
CLICK
Created by /Jason A Myers @jasonamyers
BUILDING GOOD COMMAND LINE
APPLICATIONS IS HARD
IMPORTANT PARTS
NAME
ARGUMENT PARSING AND VALIDATION *
HELP GENERATION *
COMMAND STRUCTURE *
AUTOCOMPLETION
NICE OUTPUT
PACKAGING *
ARGUMENTS AND HELP
THREE DIFFERENT PARSERS IN THE
STDLIB
getopt
optparse
argparse
I MEAN ARGPARSE IS THE NEW HOTNESS???
SERIOUSLY WHO KNOWS HOW
*!@%PARSE WORKS ANYWAY
NO REALLY HAVE YOU LOOKED AT
THE DOCS...
SERIOUSLY BRAIN CELLS EXPLODE
HOW BAD IS IT?
docopt
Plac
Cliff
Clint
import sys
if __name__ == "__main__":
main(sys.argv)
DEMO
LOGGING
GOOD LOGGING MESSAGES
Time
Module
Level
Parseable Messages
2015-05-28 09:25:18,711 - complex.logger - DEBUG - Creating composit
e: cookies
2015-05-28 09:25:18,711 - complex.logger - DEBUG - Created composite
: cookies
JAM'S LOGGING STYLE
import logging
logger = logging.getLogger(__name__)
logger.setLevel(logging.ERROR)
file_log_handler = logging.FileHandler('complex-cli.log')
logger.addHandler(file_log_handler)
stderr_log_handler = logging.StreamHandler()
logger.addHandler(stderr_log_handler)
format_string = '%(asctime)s - %(name)s - ' 
'%(levelname)s - %(message)s'
formatter = logging.Formatter(format_string)
file_log_handler.setFormatter(formatter)
stderr_log_handler.setFormatter(formatter)
PACKAGING
FIND OUR MODULE
from setuptools import setup, find_packages
setup(
name='complex',
version='0.1.2',
packages=find_packages(),
include_package_data=True,
install_requires=[
'Click==3.3',
],
description='A description',
classifiers=[
'License :: OSI Approved :: BSD License',
'Programming Language :: Python',
'Programming Language :: Python :: 3',
],
entry_points='''
[console_scripts]
complex=complex.command:cli
'''
)
COMPLEX DEMO
QUESTIONS
@JASONAMYERS

Contenu connexe

Similaire à Building CLIs that Click

DDD on example of Symfony (SfCampUA14)
DDD on example of Symfony (SfCampUA14)DDD on example of Symfony (SfCampUA14)
DDD on example of Symfony (SfCampUA14)Oleg Zinchenko
 
Serverless in production, an experience report (LNUG)
Serverless in production, an experience report (LNUG)Serverless in production, an experience report (LNUG)
Serverless in production, an experience report (LNUG)Yan Cui
 
DevSecCon London 2017 - MacOS security, hardening and forensics 101 by Ben Hu...
DevSecCon London 2017 - MacOS security, hardening and forensics 101 by Ben Hu...DevSecCon London 2017 - MacOS security, hardening and forensics 101 by Ben Hu...
DevSecCon London 2017 - MacOS security, hardening and forensics 101 by Ben Hu...DevSecCon
 
DevOps with Serverless
DevOps with ServerlessDevOps with Serverless
DevOps with ServerlessYan Cui
 
Charla EHU Noviembre 2014 - Desarrollo Web
Charla EHU Noviembre 2014 - Desarrollo WebCharla EHU Noviembre 2014 - Desarrollo Web
Charla EHU Noviembre 2014 - Desarrollo WebMikel Torres Ugarte
 
Serverless in Production, an experience report (cloudXchange)
Serverless in Production, an experience report (cloudXchange)Serverless in Production, an experience report (cloudXchange)
Serverless in Production, an experience report (cloudXchange)Yan Cui
 
2 Roads to Redemption - Thoughts on XSS and SQLIA
2 Roads to Redemption - Thoughts on XSS and SQLIA2 Roads to Redemption - Thoughts on XSS and SQLIA
2 Roads to Redemption - Thoughts on XSS and SQLIAguestfdcb8a
 
Cloud patterns applied
Cloud patterns appliedCloud patterns applied
Cloud patterns appliedLars Fronius
 
20201010 - Collabdays 2020 - Sandro Pereira - Power Automates: best practice...
20201010 -  Collabdays 2020 - Sandro Pereira - Power Automates: best practice...20201010 -  Collabdays 2020 - Sandro Pereira - Power Automates: best practice...
20201010 - Collabdays 2020 - Sandro Pereira - Power Automates: best practice...Sandro Pereira
 
WebCamp: Developer Day: DDD in PHP on example of Symfony - Олег Зинченко
WebCamp: Developer Day: DDD in PHP on example of Symfony - Олег ЗинченкоWebCamp: Developer Day: DDD in PHP on example of Symfony - Олег Зинченко
WebCamp: Developer Day: DDD in PHP on example of Symfony - Олег ЗинченкоGeeksLab Odessa
 
[DSC Europe 22] Smart approach in development and deployment process for vari...
[DSC Europe 22] Smart approach in development and deployment process for vari...[DSC Europe 22] Smart approach in development and deployment process for vari...
[DSC Europe 22] Smart approach in development and deployment process for vari...DataScienceConferenc1
 
Julien Simon "Scaling ML from 0 to millions of users"
Julien Simon "Scaling ML from 0 to millions of users"Julien Simon "Scaling ML from 0 to millions of users"
Julien Simon "Scaling ML from 0 to millions of users"Fwdays
 
DN 2017 | Reducing pain in data engineering | Martin Loetzsch | Project A
DN 2017 | Reducing pain in data engineering | Martin Loetzsch | Project ADN 2017 | Reducing pain in data engineering | Martin Loetzsch | Project A
DN 2017 | Reducing pain in data engineering | Martin Loetzsch | Project ADataconomy Media
 
PowerShell - Be A Cool Blue Kid
PowerShell - Be A Cool Blue KidPowerShell - Be A Cool Blue Kid
PowerShell - Be A Cool Blue KidMatthew Johnson
 
Network OS Code Coverage demo using Bullseye tool
Network OS Code Coverage demo using Bullseye toolNetwork OS Code Coverage demo using Bullseye tool
Network OS Code Coverage demo using Bullseye toolVikram G Hosakote
 
The Dirty Little Secrets They Didn’t Teach You In Pentesting Class
The Dirty Little Secrets They Didn’t Teach You In Pentesting ClassThe Dirty Little Secrets They Didn’t Teach You In Pentesting Class
The Dirty Little Secrets They Didn’t Teach You In Pentesting ClassRob Fuller
 

Similaire à Building CLIs that Click (20)

DDD on example of Symfony (SfCampUA14)
DDD on example of Symfony (SfCampUA14)DDD on example of Symfony (SfCampUA14)
DDD on example of Symfony (SfCampUA14)
 
Serverless in production, an experience report (LNUG)
Serverless in production, an experience report (LNUG)Serverless in production, an experience report (LNUG)
Serverless in production, an experience report (LNUG)
 
DevSecCon London 2017 - MacOS security, hardening and forensics 101 by Ben Hu...
DevSecCon London 2017 - MacOS security, hardening and forensics 101 by Ben Hu...DevSecCon London 2017 - MacOS security, hardening and forensics 101 by Ben Hu...
DevSecCon London 2017 - MacOS security, hardening and forensics 101 by Ben Hu...
 
Nodevember 2015
Nodevember 2015Nodevember 2015
Nodevember 2015
 
DevOps with Serverless
DevOps with ServerlessDevOps with Serverless
DevOps with Serverless
 
Techniques for Preserving Scientific Software Executions: Preserve the Mess o...
Techniques for Preserving Scientific Software Executions: Preserve the Mess o...Techniques for Preserving Scientific Software Executions: Preserve the Mess o...
Techniques for Preserving Scientific Software Executions: Preserve the Mess o...
 
Charla EHU Noviembre 2014 - Desarrollo Web
Charla EHU Noviembre 2014 - Desarrollo WebCharla EHU Noviembre 2014 - Desarrollo Web
Charla EHU Noviembre 2014 - Desarrollo Web
 
Serverless in Production, an experience report (cloudXchange)
Serverless in Production, an experience report (cloudXchange)Serverless in Production, an experience report (cloudXchange)
Serverless in Production, an experience report (cloudXchange)
 
2 Roads to Redemption - Thoughts on XSS and SQLIA
2 Roads to Redemption - Thoughts on XSS and SQLIA2 Roads to Redemption - Thoughts on XSS and SQLIA
2 Roads to Redemption - Thoughts on XSS and SQLIA
 
Cloud patterns applied
Cloud patterns appliedCloud patterns applied
Cloud patterns applied
 
20201010 - Collabdays 2020 - Sandro Pereira - Power Automates: best practice...
20201010 -  Collabdays 2020 - Sandro Pereira - Power Automates: best practice...20201010 -  Collabdays 2020 - Sandro Pereira - Power Automates: best practice...
20201010 - Collabdays 2020 - Sandro Pereira - Power Automates: best practice...
 
WebCamp: Developer Day: DDD in PHP on example of Symfony - Олег Зинченко
WebCamp: Developer Day: DDD in PHP on example of Symfony - Олег ЗинченкоWebCamp: Developer Day: DDD in PHP on example of Symfony - Олег Зинченко
WebCamp: Developer Day: DDD in PHP on example of Symfony - Олег Зинченко
 
Data Encryption at Rest
Data Encryption at RestData Encryption at Rest
Data Encryption at Rest
 
Azure from scratch part 4
Azure from scratch part 4Azure from scratch part 4
Azure from scratch part 4
 
[DSC Europe 22] Smart approach in development and deployment process for vari...
[DSC Europe 22] Smart approach in development and deployment process for vari...[DSC Europe 22] Smart approach in development and deployment process for vari...
[DSC Europe 22] Smart approach in development and deployment process for vari...
 
Julien Simon "Scaling ML from 0 to millions of users"
Julien Simon "Scaling ML from 0 to millions of users"Julien Simon "Scaling ML from 0 to millions of users"
Julien Simon "Scaling ML from 0 to millions of users"
 
DN 2017 | Reducing pain in data engineering | Martin Loetzsch | Project A
DN 2017 | Reducing pain in data engineering | Martin Loetzsch | Project ADN 2017 | Reducing pain in data engineering | Martin Loetzsch | Project A
DN 2017 | Reducing pain in data engineering | Martin Loetzsch | Project A
 
PowerShell - Be A Cool Blue Kid
PowerShell - Be A Cool Blue KidPowerShell - Be A Cool Blue Kid
PowerShell - Be A Cool Blue Kid
 
Network OS Code Coverage demo using Bullseye tool
Network OS Code Coverage demo using Bullseye toolNetwork OS Code Coverage demo using Bullseye tool
Network OS Code Coverage demo using Bullseye tool
 
The Dirty Little Secrets They Didn’t Teach You In Pentesting Class
The Dirty Little Secrets They Didn’t Teach You In Pentesting ClassThe Dirty Little Secrets They Didn’t Teach You In Pentesting Class
The Dirty Little Secrets They Didn’t Teach You In Pentesting Class
 

Plus de Jason Myers

Introduction to SQLAlchemy ORM
Introduction to SQLAlchemy ORMIntroduction to SQLAlchemy ORM
Introduction to SQLAlchemy ORMJason Myers
 
Filling the flask
Filling the flaskFilling the flask
Filling the flaskJason Myers
 
Spanning Tree Algorithm
Spanning Tree AlgorithmSpanning Tree Algorithm
Spanning Tree AlgorithmJason Myers
 
Introduction to Pandas
Introduction to PandasIntroduction to Pandas
Introduction to PandasJason Myers
 
SQLAlchemy Core: An Introduction
SQLAlchemy Core: An IntroductionSQLAlchemy Core: An Introduction
SQLAlchemy Core: An IntroductionJason Myers
 
Generating Power with Yield
Generating Power with YieldGenerating Power with Yield
Generating Power with YieldJason Myers
 
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic MigrationsIntroduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic MigrationsJason Myers
 
Diabetes and Me: My Journey So Far
Diabetes and Me: My Journey So FarDiabetes and Me: My Journey So Far
Diabetes and Me: My Journey So FarJason Myers
 
Selenium testing
Selenium testingSelenium testing
Selenium testingJason Myers
 
Coderfaire Data Networking for Developers
Coderfaire Data Networking for DevelopersCoderfaire Data Networking for Developers
Coderfaire Data Networking for DevelopersJason Myers
 

Plus de Jason Myers (10)

Introduction to SQLAlchemy ORM
Introduction to SQLAlchemy ORMIntroduction to SQLAlchemy ORM
Introduction to SQLAlchemy ORM
 
Filling the flask
Filling the flaskFilling the flask
Filling the flask
 
Spanning Tree Algorithm
Spanning Tree AlgorithmSpanning Tree Algorithm
Spanning Tree Algorithm
 
Introduction to Pandas
Introduction to PandasIntroduction to Pandas
Introduction to Pandas
 
SQLAlchemy Core: An Introduction
SQLAlchemy Core: An IntroductionSQLAlchemy Core: An Introduction
SQLAlchemy Core: An Introduction
 
Generating Power with Yield
Generating Power with YieldGenerating Power with Yield
Generating Power with Yield
 
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic MigrationsIntroduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
 
Diabetes and Me: My Journey So Far
Diabetes and Me: My Journey So FarDiabetes and Me: My Journey So Far
Diabetes and Me: My Journey So Far
 
Selenium testing
Selenium testingSelenium testing
Selenium testing
 
Coderfaire Data Networking for Developers
Coderfaire Data Networking for DevelopersCoderfaire Data Networking for Developers
Coderfaire Data Networking for Developers
 

Dernier

Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEarley Information Science
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsRoshan Dwivedi
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 

Dernier (20)

Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 

Building CLIs that Click