Archive for the 'Python' Category

Python: Dealing with unknown fields in dataclass

Wednesday, July 31st, 2024

I have been using dataclasses in my python data retrieval scripts but on the occasions when a field is added to the API return I needed a way to make the scripts continue to run. The added benefit of notifying the script user about any unknown fields helps too.

The following code with a Warning message to show any fields that are not predefined in the dataclass.

from dataclasses import dataclass
from dataclasses import fields

def filter_unexpected_fields(cls):
    original_init = cls.__init__

    def new_init(self, *args, **kwargs):
        expected_fields = {field.name for field in fields(cls)}
        cleaned_kwargs = {key: value for key, value in kwargs.items() if key in expected_fields}
        unknown_kwargs = {key: value for key, value in kwargs.items() if key not in expected_fields}
        original_init(self, *args, **cleaned_kwargs)
        # Handle unknown fields (optional)
        if unknown_kwargs:
            # Log a warning or raise an exception based on your needs
            print(f"Warning: Unknown fields found: {unknown_kwargs}")
    cls.__init__ = new_init
    return cls

@filter_unexpected_fields
@dataclass
class Application:
     id: int
     name: str

a1 = { 'id': 1, 'name': 'WebGoat',"runs":5}
app = Application(**a1)



So given the following code, the “runs” field is not defined in the dataclass object, but with the “@filter_unexpected_fields” decorator, the code will continue to work but the additional warning message will notify about any undefined fields.
1 based on answer on this page: https://stackoverflow.com/questions/54678337/how-does-one-ignore-extra-arguments-passed-to-a-dataclass

Python: pip certificate failure

Monday, February 5th, 2024

I recieved a new laptop and the Python certificates were failing for me. The quickest, but not necessarily the most secure method for fixing this is to either use the –trusted-host entry for each host that throws a certificate exception or to create a file in the ~/.config/pip/pip.conf file like the one below. This covers the main sites that pip uses to install packages.

[global]
trusted-host = pypi.python.org
               pypi.org
               files.pythonhosted.org

Python: Convert int to String for output

Wednesday, November 4th, 2020

I was creating a new program and wanted to generate an output string that showed the count of certain types of entries. When I attempted the simple output to get “Number of rows: 5” by using the following:

Incorrect call

rowcount = 100
print("Number of Rows: " + rowcount) 

I got the following error “TypeError: can only concatenate str (not “int”) to str” . This meant that the type of rowcount was an int but needed to be a string. There is a handy function call that takes the int and converts it to a string. The function is str() and it converts the int argument to a string value.

rowcount = 100
print("Number of Rows: " + str(rowcount))

There are other ways to output a number such as ‘%s’, format and f-string. But for my purposes. ‘str’ gave me the debugging info I needed.

Tags:

Python: Conditional Assignments

Thursday, October 29th, 2020

There are times that you may want to assign a different value to a variable based on the value of another variable. This can be accomplished in many compiled languages with the ternary operator.

In Python the syntax for this is different because python was written to allow you to read a line of code and have a better understanding of what the code is doing. Python uses conditional assignment where you can use an if statement to help decide what the variable should be assigned.

a = "Happy" if weather == "sunny" else "Sad"

So reading this code states: “a is set to “Happy” if weather equals sunny else a is “Sad”” .

Python Variables

Saturday, August 18th, 2018

Variables in Python are declared on first use.
Variable names in Python must:

  • Start with a letter or an underscore character
  • Not start with a number
  • Only contain alpha-numeric characters and underscores (A-Z,a-z, 0-9 and _)
  • Be case sensitive (ex. name and Name are different variables)

Good variable names

apple
b_funky
_tester

The underscore as the first character usually indicates that the function is for internal use. This convention is mentioned in PEP 8.

Bad variable names

8million
$dog
+happy

The scope of a Python variable depends where it is defined.

If it defined outside of any function or class, then that variable is global. This means that all functions can access that variable.

some_var= "Eric"

If it is defined within a class or function, than that variable is considered to have local scope.

def print_name(name):
    greeting = "Good Morning,"
    print(greeting,name)

The variable some_var is global and can be used throughout the program, but the variables name and greeting are local to the function and are not available outside of the function.

Tags:

Install Python modules to a different directory

Saturday, February 22nd, 2014

There are times that I have wanted to install some Python module on a system where I did not have access to do so.
When you do not have permission to write into the standard library directories you
may need to run the “python setup.py install” command with the additional option of

 --home=<Some other directory>

make sure that this base directory has a lib/python directory within it and that you have
exported the PYTHONPATH variable to contain this directory.

Then simply run the command “python setup.py install –home=<Some other directory>” and your libs will
be installed.

Then you will need to make sure that your PYTHONPATH environment variable is always available
to whatever runs your scripts.

As an alternative to the PYTHONPATH, you can use the following within your scripts to target a non-standard python module directory:

import sys
sys.path.append("/path/to/the/module/directory")
## import any modules you have in your own directory

Using the method in the script allows you to make the scripts available to other users that may not have the PYTHONPATH setup.

Tags:

Python: Handle Command line arguments with Optparse

Thursday, February 23rd, 2012

Here is my basic script for handling command line arguments in Python(pre version 2.7 when optparse
was deprecated). The optparse library is very useful in not only handling the command line
arguments, but setting up your help menu as well.

You will need to create an OptionParser and the usage argument lets you print the usage statement
for the script. Then you can add options, add groups for options or collect the left over
parameters as a secondary command or list of files. I use this method often as I create scripts
that help automate build processes.

#!/usr/bin/python

import sys, optparse

# This creates an OptionParser object with the usage string.
op = optparse.OptionParser(usage=" %prog [options]")
# This will add an option -m or --mode which takes sets the mode variable as
# True or False
op.add_option("-m","--mode",help="Specify the mode for the command", 
            action="store_true", dest="mode",default=False)
# This parses the options and places the selected options above in the _options
# object and the rest in arguments.
_options,arguments = op.parse_args()

# Checks if no arguments are passed and if so, runs the print_help method of 
# the OptionParser object
if len(sys.argv) == 1:
    op.print_help()

# This was just to show what happened when you did or didn't pass the
# --mode argument.
if  _options.mode:
    print "Mode is on"
else:
    print "Mode is off"

This method is currently deprecated as of version 2.7. I will write a follow-up post that uses
the newer argparse routine to highlight any differences.

Tags: ,

Python: if/else Statements

Friday, January 20th, 2012

There comes a time when you are writing a program and you need to branch based on input to a program.
This is the format of the if/else statement in Python.

if <some true/false statement> :
  <some statements that run if the if statement is true>
else:
  <some other statements that run if the if statement are false>  

There may be times when you have more than one value set to test against. In that case you can write a many if/else
statements but you can chain the if/else statements with an elif. So the chain becomes if/elif/else.

if x < 5:
  <some statements that run if the if statement is true>
elif x > 5 and x < 10:
  <some statements that run if the elif statement is true>
else:
  <if none of the if checks are true, run the statements in the else case.>

Tags: ,

Python: Allow for empty if else blocks

Friday, January 20th, 2012

I was toying with a prime number finder and was creating a set of if/else statements for a horribly failed attempt
and wanted to skip to the next number on any of the if statements that were true. I didn’t want to put an empty print
statement as that would disrupt the output I was expecting from the program. I found the pass statement.
Here is an example from my not very successful attempt at finding primes:

if inp > 2 and inp % 2 == 0:
  pass
elif inp > 3 and inp % 3 == 0:
  pass
elif inp > 7 and inp % 7 == 0:
  pass
elif inp > 9 and inp % 9 == 0:
  pass
else:
  print inp, " is a prime"

Yes, this does not accurately find the primes, but it would skip any number that is divisible by 2,3,5,7, or 9. And
anything that does not match this will be listed as a prime, this is incorrect and would be made to add new elif
statements as each prime was found.

Tags: ,

How to exit python script

Tuesday, August 23rd, 2011

When I was trying to terminate a python script after a failure, I tried to find the nicest way to exit. The sys.exit() command provided by importing the sys library was what I found.

The function can take an optional numeric argument, usually in the range of 0-127, and with no argument it returns 0. The return code is passed back to the Operating System.

import sys
sys.exit(1)

When exit returns a non-zero value, it is considered an error.

Tags: