Giter VIP home page Giter VIP logo

weather_cli's Introduction

weather_cli

Command line tool which presents weather data in a customizable format. This was originally created by following a series of tutorials on how to use click for handling command line arguments. I have since expanded upon and made this program into my own. Plan is to keep expanding upon it, and eventually add a 5-day forecast mode.

Pull requests, issues, comments and criticisms are more than welcome.

The start of it all:

Demo

Short series of demo commands to show off a bit. Why not. The arguments can be specified in a variety of ways, as can be seen in the commands being entered. Full documentation for the available arguments can be found by passing the --help argument as noted in the installation instructions.

$ weather current Mars -Cthw --units imperial
Light rain | ↑34°F, 32.76°F, ↓32°F | 87%RH | NNW at 3.36mph
$ weather current Mars -Cthw -u standard --pretty long
Current conditions for Mars are
    Light rain at ↑274.26°K, 273.5°K, ↓272.59°K
      87%RH, winds NNW at 1.5m/s
$ weather current Mars -Cthw --units=metric -p verbose
Location: Mars
Conditions: Light rain
Temperature (High, Current, Low): ↑1.11°C, 0.42°C, ↓0°C
Relative Humidity: 87%RH
Wind (Direction, Speed): NNW, 1.5m/s

API Key

This program requires a free OpenWeatherMap API Key. Once you have your key, it may be passed into the program by either a configuration file or a command line argument. It is recommended to run weather in interactive mode and allow it to save the API key to configuration file. Using interactive mode will prevent you from entering your key into the terminal, which would leave it sitting in your history file for any with access to see.

# Install API key interactively
$ weather config
Please enter your OpenWeatherMap API key: YOUR_API_KEY [return]
# Install API key from command line
$ weather --api-key YOUR_API_KEY config

Obtain your API key here: https://openweathermap.org/appid

Installation

The install and use should be fairly simple. I don't totally know what I'm doing with setuptools but this works, and has been verified in local clones of this repo. If errors are encountered with these instructions, an issue or comment would be appreciated so I can fix it.

These instructions will install weather_cli into a virtual environment and create an executable, weather, within that environment. When called, that executable automatically enables the virtual environment, runs our program, and deactivates the virtual environment.

# Clone the repo
git clone https://github.com/ncdulo/weather_cli.git
cd weather_cli

# Create a new virtual environment, and enable it
python -m venv .env
source .env/bin/activate

# Update Pip & friends. Optional, but recommended
python -m pip install --upgrade pip setuptools wheel

# Install dependencies and create executable
pip install .

# Deactivate the virtual environment
deactivate

# Write your API key to configuration file interactively (recommended)
.env/bin/weather config
# -- or as a single command --
.env/bin/weather --api-key YOUR_API_KEY config

# Check use instructions
.env/bin/weather --help
.env/bin/weather config --help
.env/bin/weather current --help

# Optional, install symlink to executable within your $PATH
# ~/.local/bin must be in your system $PATH
ln -s `pwd`/.env/bin/weather ~/.local/bin/weather
# With the symlink in place, `weather` may be called from any location
# without typing the full path to the executable

weather_cli's People

Contributors

ncdulo avatar

Stargazers

 avatar  avatar

weather_cli's Issues

[Feature Request] 5-day Forecast

Is your feature request related to a problem? Please describe.
While not strictly a problem, being able to display the current 5-day forecast is a staple feature in any weather checking program, in my opinion. OpenWeatherMap API provides this data -- utilize it!

Describe the solution you'd like
The forecast mode will be a separate top-level command from current. This will effectively split our operating modes in two so that each is contained separately. The OpenWeatherMap data provides 5-days worth of forecast data, at 3 hour intervals. Determine a pretty-print format, possibly with the calendar module, so that we can properly display that data. We may instead want to use a more generic table-formatting module if calendar feels limiting or does not allow us the proper control over formatting.

The end result should be the ability for the user to query a location for the 5-day forecast, with the same set of options as current would take for controlling which data to display. Output should be nicely formatted into a table, or similar structure so that it is easy to read. Ideally we want to fit our table width into a single standard terminal screen of 80x25 columns such that there should be no line breaks or broken formatting under normal circumstances.

Describe alternatives you've considered
One potential alternative is a strictly text based forecast display. Where instead of a table, you get small paragraphs or blurbs for each day in the forecast. I don't think this would translate well into final output. There would be far more data than can easily be scanned with the eye when you include 5-days at 3 hour intervals.

Additional context
The data returned by OpenWeatherMap will include a list with numbered elements for each 3-hour block. The number is cumulative as it is simply a list index, not a prediction number for each day. Therefore instead of grabbing the temperature as weather['main']['temp'], we would grab the temperature as weather[XX]['main']['temp'], where XX can be represented by day_number * hour_offset. That probably doesn't make total sense. Play with the data a bit in the REPL to help visualize how it is laid out before starting to implement our output loops.

[BUG] Program fails when data missing from API call

Describe the bug
When running the current command to query current weather conditions from OpenWeatherMap it is possible for the program to fail with a KeyError when pieces of the data being expected are not present. The missing data is due to OpenWeatherMap not having data for that parameter to return. That is a perfectly normal condition and we should exit gracefully when it is encountered.

To Reproduce
This bug may not appear every time, under every condition. Takes a bit of playing around with different locations, and different flags to find a location where not all data is available. The command I have been able to consistently cause this KeyError with is:

weather current Dubai --wind

Expected behavior
Rather than not handling the error and allowing Python to throw a Traceback all over the console, we should catch the error and handle it accordingly. This may include simply omitting the data from the output, or including a warning about the parameter not being returned from the API. The user should not have to dig through a Traceback simply because OpenWeatherMap does not know the humidity, or wind speed, etc, for a given location.

Output

[$] [1] <git:(master)> .env/bin/weather current Dubai --wind
Traceback (most recent call last):
  File ".env/bin/weather", line 11, in <module>
    load_entry_point('weather', 'console_scripts', 'weather')()
  File "/home/ncdulo/dev/projects/weather_cli/.env/lib64/python3.6/site-packages/click/core.py", line 829, in __call__
    return self.main(*args, **kwargs)
  File "/home/ncdulo/dev/projects/weather_cli/.env/lib64/python3.6/site-packages/click/core.py", line 782, in main
    rv = self.invoke(ctx)
  File "/home/ncdulo/dev/projects/weather_cli/.env/lib64/python3.6/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/ncdulo/dev/projects/weather_cli/.env/lib64/python3.6/site-packages/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/ncdulo/dev/projects/weather_cli/.env/lib64/python3.6/site-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/home/ncdulo/dev/projects/weather_cli/.env/lib64/python3.6/site-packages/click/decorators.py", line 21, in new_func
    return f(get_current_context(), *args, **kwargs)
  File "/home/ncdulo/dev/projects/weather_cli/cli.py", line 166, in current
    wind_cardinal = degrees_to_cardinal(weather['wind']['deg'])
KeyError: 'deg'

Desktop (please complete the following information):

  • OS/Distribution: Gentoo Linux 17.1 Desktop
  • Python 3.6.10
  • requests-2.23.0
  • click-7.1.1
  • Python virtual environment? Yes

Additional context
A similar bug will manifest when the location name is not found by OpenWeatherMap. If the location name is not found, the request will still return perfectly fine. However there will be no data for us to use, and we fail with relatively the same KeyError. I am rolling this into a single bug report as error checking and handling falls under the same tree.

[BUG] Output formatting incorrect when some flags disabled

Describe the bug
When weather is called with a partial set of output flags, there are gaps in the --pretty output where disabled data would reside. This is not ideal. The gaps are distracting and leave us with dirty output.

To Reproduce
Call weather current with a partial set of weather output options (-C/-t/-h/-w)

Expected behavior
Display text should be adjusted to compensate for disabled flags, or missing data. When flag is disabled, the text should silently skip over that section and output like it's not even there. When flag is enabled, but the data is missing from the response, return a NaN-type value. Example:

# Temperature flag disabled, Wind flag missing data
weather current Mars --pretty long -Chw 
Current conditions for Mars are
    Light snow
      87%RH, winds NaN at NaN m/s

Compare to actual output in the next section.

Output

weather current Mars --pretty long -Ch 
Current conditions for Mars are
    Light snow at 
      87%RH, winds  at

Desktop (please complete the following information):

  • OS/Distribution: Gentoo Linux 17.1 Desktop
  • Python 3.6.10
  • requests-2.23.0
  • click-7.1.1
  • Python virtual environment? Yes

Additional context
None required at this time.

[Feature Request] Properly package `weather`

Is your feature request related to a problem? Please describe.
Currently, our package is beginning to fill up. Support files, documentation, source files. All of it sitting in the top-level directory. This worked fine when it was a couple files. Now it is getting hard to manage. I don't expect it to get better on it's own either, so issue time.

Describe the solution you'd like
Using some ideas taken from guides related to Python project packaging, I would like to see weather packaged into something proper for upload to PyPi. We already have the basic framework in place, I believe. However, we will need to restructure the source directory and create a namespace for weather. This will also necessitate updating filenames, README.md instructions, setup.py, and likely other things as well.

This doesn't seem to complicated, will just require working carefully. Pay attention when doing the work. Test frequently. Ensure we don't have an issue like in another project where we committed bad files. Repeatedly.

Describe alternatives you've considered
The current organization of the repository files can be considered an alternative to the solution described above. It worked fine for just a couple files. Now it has grown unwieldy and difficult to maintain.

Additional context
No additional context required at this time.

[Feature Request] Templates for `pretty` formats

Is your feature request related to a problem? Please describe.
Depending on how you look at it, this could be classed as a bug, or a feature (request). For now, I lean towards calling it a feature request as it is more fixing design issues with the current implementation as opposed to fixing incorrect operation.

Currently, the output string in current() is assembled through a lot of dirty string concatenation. Chaining strings together as we go through our flags. This mostly works. However, I have been running into places where I have trouble extending the code. Or having a hard time when trying to add additional --pretty formats. The current implementation does the bare minimum to just work, but nothing extra in the way of allowing for future expansion.

Describe the solution you'd like
I would like to utilize the string.Template class to handle out output format. This will allow us to build a collection of output templates, and then substitute in OpenWeatherMap data. I am wondering how best to handle the cases where certain pieces of data are missing. I think either silently skipping that parameter, or initializing it to a NaN-type value would handle it. The latter is probably preferable.

Describe alternatives you've considered
The alternative solution is to keep banging away with string concatenation and hard to maintain code. Don't do that.

Additional context
The implementation described here will require an update of the --pretty flag into an option. It will also require updating each if {conditions,temperature,...} block within the current() function so that they assign to their own variable, instead of the output string. Whether we should over-write the same variable that we test for with the output string is yet to be determined. An example being:

# This
if conditions:
    conditions = 'partly cloudy'
# Or this
if conditions:
    conditions_text = 'partly cloudy'
else:
    conditions_text = None

I tend to lean towards the latter solution, otherwise we will need to check for potential True values being given to our output template when the flag is enabled, but the data is unavailable. That is an issue I ran into before when trying a very early implementation of this feature. That attempt was not well thought through and resulted in more problems than solutions. I unfortunately did not think to save the work and simply git reset it out of existence.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.