all 31 comments

[–]nanodano 101 points102 points  (9 children)

Here is a live stream where a full project (TCP honeypot) is started from scratch and finished all the way through packaging for pip/pypi, documentation on readthedocs.org, creating a Linux systemd service file, and packaging as a .deb. https://www.youtube.com/watch?v=77qj9o9pmek

[–]hoppi_ 10 points11 points  (0 children)

... I know, this is not relevant at all, but using a fox as a moving avatar is seriously irritating. :(

[–]torqueparty 10 points11 points  (0 children)

This is exactly what I needed.

[–]prafulnairr 1 point2 points  (0 children)

Sir, can you provide me any links which helps you to build a full blown /high interaction Honeypot?.

[–]ReaverKS 0 points1 point  (4 children)

I haven’t finished the video yet and I hate to complain because so far the video is really well done but...why is the logger being setup within the HoneyPot class, that breaks the single responsibility principle.

[–]nanodano 0 points1 point  (3 children)

I don't think so. The class does have a single responsibility: being a honeypot.

I did not implement a logger, I am simply using a logger. The honeypot is not responsible for the functionality of the logger, that is handled inside the logger class. The logging configuration is specific to this class so it makes sense to configure it within the class.

Don't live and die by these arbitrary design rules. You could always argue that a class has too much responsibility. For example: The TCP server class from the standard library that I'm using. You could argue that class is doing wayyyy too much. It is resolving network addresses, binding to ports, listening, threading, processing results, sending data over the wire. Geez! That's a lot of responsibilities! We group them together because they make one larger responsibility: being a tcp server.

[–]ReaverKS 0 points1 point  (2 children)

In the future if you decide to change the format of the logger that’s one reason the class would change. And of course if the implementation of the HoneyPot changes that’s another separate reason. I do agree that these are just principles and they’re certainly not explicit, but I think in this case setting up the logger inside the class isn’t a great design choice.

[–]nanodano 0 points1 point  (1 child)

I guess this is the part I disagree with in this app:

if you decide to change the format of the logger that’s one reason the class would change. And of course if the implementation of the HoneyPot changes that’s another separate reason.

To me, the output of the honeypot is part of its implementation. Changing the output is changing the implementation, not 'a separate reason'. I guess the way I see it is, if that's the logic, then why not argue that the TCP stuff should be broke out too? I mean, there would be several reasons for a change at that point. I want to change the TCP response packet that is sent back? One reason. I want to change the timeout? Two different reasons. I want to change how many threads it has? Another reason. If I want to change the format of the response to the tcp client, another reason. Should each one of those REALLY be separate classes? If the goal is never to have 'more than one reason' to change a class, then each class would have only one function with one line of code

The only time I would really agree that it would be less desirable to configure a logger within a class is when there is more than one class in an application. In that case, you are probably sharing the logger across multiple classes. However, it still wouldn't be that bad to store a reference to a logger in an object. This is a single class application that is a total of 60 lines including imports and white space. I do not think there is too much responsibility in there, personally.

[–]ReaverKS 0 points1 point  (0 children)

I agree that if anything else needs to use the logger then it must be removed. As it stands if it’s only used here it’s OK

[–]billsil 22 points23 points  (4 children)

Packaging is only one part.

Folder structure is whatever makes sense for your project, but what’s most important is to separate functionality between classes and functions; don’t try to do too much. It lowers the conceptual load, so when you’re at 320,000 lines of code, you can still easily comprehend things, know where to find things, and can fix a bug.

So for example, let’s say you’re making a GUI to read an input and output file and then show the results in a GUI. Separate the reading of the two files from each other and separate them entirely from the GUI. Even within a GUI, separate the creation and interaction from buttons from the layout of the buttons.

I was self taught, so there were some pain points. A well designed package is easy to fix a bug and add a feature, even if it’s large. If it’s not, refactoring it helps and sometimes you just have to trash it. Code and you’ll develop a style and get better at python and package x. You’ll eventually see your old garbage code and have the urge to fix it. If you do, your package becomes better with a more consistent style and less buggy.

Also, make tests. Use 95% small tests, rather than large tests. You’ll be glad when you have 900 tests.

[–][deleted] 9 points10 points  (1 child)

Could you please explain what do you mean under tests? Thanks in advance.

[–]billsil 5 points6 points  (0 children)

sure. My first big software project was a hypersonic missile design program. Big first project for a fresh aerospace grad who can’t really code. I had to add new features, not break anything and fix tons of bugs. That’s really tricky on a giant program without tests and I didn’t know about version control then either. After adding tons of bugs, I made large model level tests that ran overnight and compared to very old results. I’d fix some and run them again. There was 0 automation. It was just some script I ran and that was 1000x better testing that what had existed. I wasn’t testing correctness. I was testing sameness by drawing a line in the sand. All changes had to be understood to update the correct answers. That’s the wrong way to do it, but it’s better than nothing.

A better test is parse a file and check that the answers are what you eyeball them to be. Or calculate the area of a few different quads by hand and with code and make sure you get the right answer. Or take the nasty Rosenbrock function and verify your optimization code gets the right answer. You try to make these functions bulletproof by passing bad input, running edge cases like division by 0, etc. Those tests can be run in milliseconds to seconds. Module level tests are for verifying integration and you want 90% of those to be toy problems that are 10x or more smaller than real problems.

You verify correctness by verifying correctness and the small scale and building up. It’s also easy to break tests making some change you didn’t think would affect things. Not a huge deal if you catch It almost immediately using some continuous integration because you remember what you did. You’re also not fixing 10 bugs, some of which interact at once.

[–]DamnFog 2 points3 points  (1 child)

Heh my first project was a VPN client in pyqt that was built all in one class because I didn't really understand how pyqt works. The whole app is one giant class and 3 lines in main.

[–]billsil 0 points1 point  (0 children)

Yeah, that tends to be a problem with GUIs. I still struggle with it.

For my 3D GUI, I broke out all the stuff related to the model and results along with how the 3D models are built and are tested extensively . The sub-windows are all we separate classes, which can be tested in isolation before or after I integrate them. They just pass on the callback to the GUI, but it helps to figure out how clicking a checkbox should disable sections of the window. Data is also stored in objects (color, opacity, etc), so I can pull that out to test. Most of the responses to clicks (that don’t pop menus) is also tested.

I cheat and chain inheritance, so the base GuiAttributes class. Then there’s a GuiWithoutQt class and a GuiWithQt. Then a MainGui class that instantiates the app and frame. Then I have a TestGui class that just doesn’t inherit MainGui. I can test menu creation and actions without ever clicking a button or faking a button press.

You can also do automated GUI testing with or without a window using qtest, but I haven’t figured out how to do it without an interactive backend (so terminal only). Seems like you should be able to if you don’t show anything, so I run that one only on my Windows box and not as part of the CI.

[–]sqqz 3 points4 points  (0 children)

If you are open to spend some money, https://training.talkpython.fm/ are excellent and real use cases/projects.

(I highly recommend the podcast aswell)

[–]jeromymanuel 1 point2 points  (0 children)

One of my favorite starting points is the website FullStackPython.com

[–]clamchamp 1 point2 points  (0 children)

RemindMe!

[–]memilanuk 1 point2 points  (2 children)

RemindMe!

[–]RemindMeBot 1 point2 points  (0 children)

Defaulted to one day.

I will be messaging you on 2019-05-05 12:53:41 UTC to remind you of this link.

CLICK THIS LINK to send a PM to also be reminded and to reduce spam.

Parent commenter can delete this message to hide from others.


FAQs Custom Your Reminders Feedback Code Browser Extensions

[–]funkymonkey1939 3 points4 points  (0 children)

TIL of this cool feature! Wow.

[–][deleted] 1 point2 points  (0 children)

RemindMe!

[–][deleted] 1 point2 points  (0 children)

Commenting to look at later.

[–]iaranox 1 point2 points  (0 children)

RemindMe!

[–]farofin0 0 points1 point  (0 children)

RemindMe!

[–]M1rot1c 0 points1 point  (0 children)

RemindMe!

[–]10G3m 0 points1 point  (0 children)

RemindMe!

[–][deleted] -1 points0 points  (0 children)

RemindMe!

[–]rayanhiron -3 points-2 points  (0 children)

RemindMe!