Giter VIP home page Giter VIP logo

Comments (7)

chey avatar chey commented on September 1, 2024 3

I built a decorator based on the above code snippet.

def cls_filter(*args):
    """Class Filter"""
    def wrapper(cls):
        class FireFilter(cls):
            """Filter properties"""
            def __dir__(self):
                return sorted(set(
                    dir(self.__class__)
                ).union(
                    set(self.__dict__.keys())
                ).difference(args))
        return FireFilter
    return wrapper

Use it like this (with example from above):

@cls_filter('get_invalid_upload_as_df', 'get_raw_upload_as_df')
class UploadCLI(UploadSDK):

Would be a nice to have if a filter like this was incorporated in Fire.

from python-fire.

petroslamb avatar petroslamb commented on September 1, 2024 2

Not sure if this is what you want, but in my case I subclassed and removed the methods I didn't want like so:

class UploadCLI(UploadSDK):
    def __dir__(self):
        return sorted(set(
            dir( self.__class__ )
        ).union(
            set( self.__dict__.keys())
        ).difference(
            set(['get_invalid_upload_as_df', 'get_raw_upload_as_df'])
            ))

You can go as far as altering the behaviour of the class __getattribute__, so if called it will not execute potentially dangerous code (not my case):

def __getattribute__( self, name ):
    if name in [whatever must be excluded ]: raise AttributeError( name )
    else: return super( Son, self ).__getattribute__( name )

Inspiration:

from python-fire.

dbieber avatar dbieber commented on September 1, 2024

First, you could pass the dict directly to Fire, rather than passing a class:

if __name__ == '__main__':
    fire.Fire(App.show())

This way you can run python app.py instead of python app.py show

$ python app.py
safe: safe!

Second, a simple alternative that you might like is renaming dangerous to _dangerous. This will make it hidden by default, only visible if the --verbose flag is used. Note that it can still be called from the command line. If it's not too dangerous, this is my recommended solution.

import fire

class Obj(object):
    def __init__(self):
        self.safe = 'safe!'

    def _dangerous(self):
        print('dangerous!')

if __name__ == '__main__':
    fire.Fire(Obj)

Another alternative is to use a class (instead of a dict) with just the safe stuff:

class App(object):

   def safe(self):
      obj = Obj()
      return obj.safe

if __name__ == '__main__':
    fire.Fire(App)

I don't recommend this though because it requires keeping App up to date with Obj.

from python-fire.

dbieber avatar dbieber commented on September 1, 2024

Hope this was helpful! Closing. Feel free to ask additional questions.

from python-fire.

cletomartin avatar cletomartin commented on September 1, 2024

Hey David,

thanks a lot for your feedback.

Yeah, I thought through using a wrapper class for this kind of case but my real case was particularly simple: I don't need to decorate the methods/attributes of Obj. So I thought using the dictionary (actually using it as a simple wrapper) would be the simplest solution.

Sorry, I didn't explain the case properly. Obj represents a class that I shouldn't/cannot modify. Think, for example, in a typical object for doing DB transactions and you only want to export those methods for getting information from the DB and avoid the user to use "dangerous" methods like update() or delete().

So basically, the idea would be using fire to create a cli for a instance from which I need to control what methods and attributes are exposed (that is, as actions of the cli). I think the dictionary is not a really bad solution for this case. The only subtlety is that when the action is used then it is always evaluated (as it is included in the dictionary) so there is not way to show the help message if the user does not provide a parameter for that action. So, in the example I put in the first place, it would be great that both commands:

$ python app.py show 
$ python app.py show  --help

show the help for show action:

Usage:       app show 
             app show safe

from python-fire.

dbieber avatar dbieber commented on September 1, 2024

I see what you're saying. And, yeah, I see the value of having the help be shown rather than having the dict's value shown. Currently there is no way to specify that something should always show help rather than have it's value shown. Nor is there a way to call Fire on an object while restricting the user's access to the object's members. Using a dict, class, or fn that has limited access, like you're doing, is the closest such thing.

So, the following might get you what you want without being much more verbose than the dict:

obj = Obj()
class App(object):
  safe = obj.safe

if __name__ == '__main__':
    fire.Fire(App)

(I don't know if/why you want to type show before the command, but if you do, then you could do this:)

obj = Obj()
class SafeObj(object):
  safe = obj.safe

class App(object):
  def show(self):
    return SafeObj()

if __name__ == '__main__':
    fire.Fire(App)

from python-fire.

chey avatar chey commented on September 1, 2024

There is one caveat to the above methods. It has no affect on code completion. In other words, code completion output still has the filtered attributes.

If anyone has any suggestions regarding that, I'd be interested.

from python-fire.

Related Issues (20)

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.