Comments (7)
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.
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:
- https://medium.com/@george.shuklin/why-you-cant-remove-parent-methods-in-python-d4935e6d54a4
- https://medium.com/@maouu/sorry-but-youre-wrong-aea1b88ffc03
from python-fire.
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.
Hope this was helpful! Closing. Feel free to ask additional questions.
from python-fire.
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.
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.
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)
- ERROR: Could not consume arg: >> HOT 1
- AttributeError: 'module' object has no attribute 'PY34' HOT 1
- How to set the number of args at least one? HOT 1
- Python 2.7 no longer available in GitHub Actions by default HOT 1
- Unexpected printing (+paging) when using inspect HOT 3
- Cannot parse list of strings containing `is` HOT 5
- Gracias
- unable to install fire HOT 4
- Android 14 HOT 1
- What's the meaning of "available commands: as_interger_ratio | bit_count |..." HOT 2
- How to use the avialable command "S.xx", such as S.count HOT 2
- How to pass '2e9672320848' as a str value? HOT 1
- Optional type args are mistyped in help HOT 4
- Have all staff been laid off? HOT 1
- FEATURE: key:value parsing in arguments
- Replace deprecated usage of ast.Str HOT 1
- shouldn't --completion for zsh also complete paths?
- Docs don't mention when a class method is considered private v.s public / --help behavior is confusing
- Allow to supress output.
- Param Alias
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from python-fire.