www.pretzellogix.net
Open in
urlscan Pro
173.254.111.40
Public Scan
Submitted URL: http://www.pretzellogix.net/
Effective URL: https://www.pretzellogix.net/
Submission: On June 10 via api from US — Scanned from DE
Effective URL: https://www.pretzellogix.net/
Submission: On June 10 via api from US — Scanned from DE
Form analysis
1 forms found in the DOMGET https://www.pretzellogix.net/
<form role="search" aria-label="Search for:" method="get" class="search-form" action="https://www.pretzellogix.net/">
<label for="search-form-1">
<span class="screen-reader-text">Search for:</span>
<input type="search" id="search-form-1" class="search-field" placeholder="Search …" value="" name="s">
</label>
<input type="submit" class="search-submit" value="Search">
</form>
Text Content
Skip to the content Search PRETZEL LOGIX Logic so twisted, it's delicious Menu * Home * Analog * Cameras * Code * Digital * Mobile * Networking * Power * Software * Storage * About Search Search for: Close search Close Menu * Home * Analog * Cameras * Code * Digital * Mobile * Networking * Power * Software * Storage * About Categories Code STEP 15: MAKE AN APP THAT CONSUMES YOUR MODULE * Post author By Pretzel * Post date April 19, 2022 * 5 Comments on Step 15: Make an app that consumes your module After 14 simple steps, we have finally reached the point where we can leverage the new module that we have just completed. We are going to write an app!!! In fact, we are going to first write a simple 5-line prototype just to prove that it works. And then we are going to write a full-fledged windowing GUI application that runs inside our OS of choice! This kitty looks pleased with the Kitty Time! app Are you excited? Let’s go! Continue reading “Step 15: Make an app that consumes your module” * Tags API, JSON, Python, REST, SDK -------------------------------------------------------------------------------- Categories Code STEP 14: WRITING UNIT TESTS * Post author By Pretzel * Post date April 17, 2022 * 4 Comments on Step 14: Writing Unit Tests At this point, we’ve essentially completed a barebones REST API library for TheCatApi.com in Python. Now we need to write our unit tests. If you haven’t written unit tests before, this might be a good opportunity to learn some of the basics of unit testing. If you have written unit tests before and know how to do it, well, feel free to skip this chapter. No one I know actually likes writing unit tests even if they are REALLY good for the overall quality of your code. This isn’t going to be an in-depth explanation of unit testing in Python. That would take a whole book or two. Instead, we’re just going to cover the basics. (If you are interesting in learning more on your own, check out the book “Python Testing with pytest” by Brian Okken.) Continue reading “Step 14: Writing Unit Tests” -------------------------------------------------------------------------------- Categories Code DJANGO LISTVIEW METHOD EXECUTION ORDER (AND HOW TO OVERRIDE) * Post author By Pretzel * Post date March 3, 2022 * No Comments on Django ListView method execution order (and how to override) Here’s my “quick reference” on the Django ListView method execution order and how to override them: __init__() Standard when instance of class is created setup() Initializes: self.request, self.args, and self.kwargs Overriding this method allows mixins to setup instance attributes for reuse in child classes. When overriding this method, you must call super(). dispatch() Re-directs at GET to get(), POST to post(), etc. http_method_not_allowed() Called only when dispatch() cannot properly dispatch to GET get() Calls methods in the following order: get_template_names() Simple method that gets either (but not both): – the template_name from a variable – the object modelname get_queryset() Gets the queryset; must be an iterable get_context_object_name() Simple method that gets either: – the template_name from a variable context_object_name – the object model_name appended with _list get_context_data() Sets the viewbag/dictionary for the Jinja template render_to_response() This is called last using return keyword to return a “response_class” instance to dispatch() -------------------------------------------------------------------------------- Important Notes: if you override get(), you must explicitly call get_queryset() and get_context_data() in your own version of get(). You might also need to implement both methods as well. You can implement any or all 4 methods, but you aren’t required to override get(). The dispatch() method will do that. The most common configuration is to implement your own get_queryset() and (sometimes) implement get_context_data() calling the super() method first. The custom get_context_data() method allows you to “tack on” extra context. See the official Django ListView docs for more details: https://docs.djangoproject.com/en/dev/ref/class-based-views/generic-display/#listview * Tags Django, Python -------------------------------------------------------------------------------- Categories Code STEP 13: PAGING THE ENDPOINTS * Post author By Pretzel * Post date December 19, 2021 * 2 Comments on Step 13: Paging the Endpoints In the last chapter, we covered how to enhance our endpoints and data models with helper methods. Now that we have a working library, it’s time to introduce the concept of “paging” our endpoints and how this helps your code perform better. What do we mean by “paging”? Simply that we can retrieve a set of results in a limited amount; a “page” at a time. Various APIs implement paging a little differently from the next. Most APIs with good documentation will actually have a full description of how their paging behaves. TheCatApi does as well. Continue reading “Step 13: Paging the Endpoints” -------------------------------------------------------------------------------- Categories Code STEP 12: CREATE MORE ENDPOINTS AND HELPER METHODS * Post author By Pretzel * Post date December 19, 2021 * 4 Comments on Step 12: Create more Endpoints and Helper Methods In the last chapter, we implemented a high-level endpoint called get_kitty(), but what if we wanted to get a clowder of kitties? We could call get_kitty() over and over again, but that incurs a lot of overhead and latency. It would be better if we just told the cat server that we wanted 10 kitties all at once instead. Let’s start by looking at our first high-level endpoint: Continue reading “Step 12: Create more Endpoints and Helper Methods” * Tags API, JSON, Python, REST, SDK -------------------------------------------------------------------------------- Categories Code STEP 11: CREATE HIGH-LEVEL ENDPOINT ABSTRACTIONS * Post author By Pretzel * Post date December 17, 2021 * 2 Comments on Step 11: Create high-level endpoint abstractions Over the past 10 chapters, we’ve created a low-level REST API adapter, refactored it, made it DRY, and implemented multiple strong data models. We even implemented inheritance! Now we’re getting to the real heart of this REST API adapter: The high-level endpoint abstractions! But we need to have a side-bar about “code smells” first… Continue reading “Step 11: Create high-level endpoint abstractions” * Tags API, JSON, Python, REST, SDK -------------------------------------------------------------------------------- Categories Code STEP 10: IMPLEMENT INHERITANCE WITH DATA MODELS * Post author By Pretzel * Post date December 8, 2021 * 4 Comments on Step 10: Implement Inheritance with data models If you’re relatively new to Object Oriented Programming (OOP), you’ve probably learned about a feature known as “inheritance“. It’s a really neat feature, but in practice and in real life… well… it isn’t used as much as you might think. As you may have noticed throughout this tutorial, we haven’t created any inheritance of our own. A common saying in the software development world is: > Favor Composition over Inheritance But why do we say that? Well, it usually comes down to flexibility. Inheritance makes code more rigid… less flexible. But it does provide a kind of “contract” on how things can or will be done. And in certain instances, it can make your code DRY-er. (Remember WET vs DRY? If not, feel free to review Chapter 3…) Wikipedia has an entry on Composition over Inheritance if you wish to read more about this: https://en.wikipedia.org/wiki/Composition_over_inheritance Continue reading “Step 10: Implement Inheritance with data models” * Tags API, JSON, Python, REST, SDK -------------------------------------------------------------------------------- Categories Code STEP 9: CREATE MORE COMPLEX DATA MODELS * Post author By Pretzel * Post date December 8, 2021 * 4 Comments on Step 9: Create more complex Data Models In the last chapter, we covered creating a strongly typed data model Fact class for the “/Fact” endpoint. Now that we have the basics down, let’s try a more advanced data model: Breed https://docs.thecatapi.com/api-reference/models/breed Taking one look at this data model, your eyes just start to glaze over, right? Write a strong data model for that?!? You must be crazy! No, what we’re going to do is leverage a website to write our Python code for us. Continue reading “Step 9: Create more complex Data Models” * Tags API, JSON, Python, REST, SDK -------------------------------------------------------------------------------- Categories Code STEP 8: CREATE STRONG DATA MODELS * Post author By Pretzel * Post date December 8, 2021 * 3 Comments on Step 8: Create Strong Data Models So here we are. We’ve created a REST API adapter! We’ve refactored our code making it DRY, added Exception handling, created a new Result model, added logging and helpful comments. And things were good. But we can do better… How so? Well, right now, our REST adapter only really helps us with setup as well as HTTP requests like GETs, POSTs, DELETEs, and any basic error handling. But it doesn’t really help us with the data we get back from TheCatAPI. Sure, you can manually access all the values in the Lists and Dictionaries if you know the magic strings, but do you really want to memorize all those magic strings? I sure don’t! How do we solve this? With Strong Data Models, of course! Continue reading “Step 8: Create Strong Data Models” * Tags API, JSON, Python, REST, SDK -------------------------------------------------------------------------------- Categories Code STEP 7: ADD HELPFUL COMMENTS TO THE CODE * Post author By Pretzel * Post date December 8, 2021 * 2 Comments on Step 7: Add helpful comments to the code Everyone knows about comments at this point, but did you know that PyCharm can help you write them? Let’s go to our __init__ constructor and put an empty line between the def line and first line of code: def __init__(self, hostname: str, api_key: str = '', ver: str = 'v1', ssl_verify: bool = True, logger: logging.Logger = None): self._logger = logger or logging.getLogger(__name__) Now type 3 double-quotes """ and hit the Enter key and PyCharm should auto-create comments like so: """ :param hostname: :param api_key: :param ver: :param ssl_verify: :param logger: """ Now we can fill them in with useful information, like this: """ Constructor for RestAdapter :param hostname: Normally, api.thecatapi.com :param api_key: (optional) string used for authentication when POSTing or DELETEing :param ver: always v1 :param ssl_verify: Normally set to True, but if having SSL/TLS cert validation issues, can turn off with False :param logger: (optional) If your app has a logger, pass it in here. """ Come to think of it, we can tighten up our constructor a little bit by making api.thecatapi.com the default hostname: def __init__(self, hostname: str = 'api.thecatapi.com', api_key: str = '', ver: str = 'v1', ssl_verify: bool = True, logger: logging.Logger = None): Lookin’ good. Try doing the same for the _do() method. What else? The _do() method could use some less formal comments. Comments aren’t just documentation, they can be notes to anyone else who uses your code (or your future self) about what you think you were doing. -------------------------------------------------------------------------------- That’s right. Comments should NOT necessarily describe WHAT you are doing step-by-step. The code should already be pretty clear about what it is doing. What comments should describe is: * What you THINK you are trying to do * WHY you are doing it (if it isn’t abundantly clear why) * HOW you are trying to do it (if what you are doing is rather complex) The reason why it is “what you THINK you are trying to do” is because the lines that you program may NOT actually do what you think you are doing. And you (or a co-worker) may come back later to debug a section of code, and you (or your co-worker) may stare at that section of code and say “well, no wonder this doesn’t work! This code doesn’t do what the comment says it is supposed to be doing.” And if you didn’t have that comment there, then it’s much harder to figure out what was supposed to be happening. Similarly, commenting on the reason WHY is also useful. Sometimes you may write code that does a thing and then come back later and wonder why you did it this way. Commenting on WHY can also be important. Lastly, writing HOW you are doing something can be helpful as well. As was mentioned previously, your code should already be pretty clear as to what it is doing. So no need to explain HOW some section of code works if it is fairly simple. Though if the code is moderately complex, it is still helpful to explain (broadly) HOW you are doing something. -------------------------------------------------------------------------------- Let’s add a few more comments: # Log HTTP params and perform an HTTP request, catching and re-raising any exceptions try: self._logger.debug(msg=log_line_pre) response = requests.request(method=http_method, url=full_url, verify=self._ssl_verify, headers=headers, params=ep_params, json=data) except requests.exceptions.RequestException as e: self._logger.error(msg=(str(e))) raise TheCatApiException("Request failed") from e That’s good, let’s try another: # Deserialize JSON output to Python object, or return failed Result on exception try: data_out = response.json() except (ValueError, JSONDecodeError) as e: self._logger.error(msg=log_line_post.format(False, None, e)) raise TheCatApiException("Bad JSON in response") from e And one more: # If status_code in 200-299 range, return success Result with data, otherwise raise exception is_success = 299 >= response.status_code >= 200 # 200 to 299 is OK log_line = log_line_post.format(is_success, response.status_code, response.reason) if is_success: self._logger.debug(msg=log_line) return Result(response.status_code, message=response.reason, data=data_out) self._logger.error(msg=log_line) raise TheCatApiException(f"{response.status_code}: {response.reason}") All that’s left is adding formal (""") parameter comments for get(), post(), delete() and the Result __init__() methods. Try it yourself! Step 8: Creating strong data models. -------------------------------------------------------------------------------- Source code: https://github.com/PretzelLogix/py-cat-api/tree/07_add_comments * Tags API, JSON, Python, REST, SDK -------------------------------------------------------------------------------- POSTS NAVIGATION ← Newer Posts1 2 … 6 Older Posts → TAGS analog API Arduino BJT breadboard camera CCENT CCNA CD-R Cisco digital DIY Django DVD+R entry-level Flash drive flash memory GoPro HDD JSON laser LED LightScribe maker MOSFET Multimeter Netduino NVMe Portable Postman PWM Python Raspberry Pi REST SanDisk sd card SDK SJCAM SSD USB USB3 Video Wii Wii U XMP RECENT POSTS * Step 15: Make an app that consumes your module * Step 14: Writing Unit Tests * Django ListView method execution order (and how to override) * Step 13: Paging the Endpoints * Step 12: Create more Endpoints and Helper Methods RECENT COMMENTS * Pretzel on Step 9: Create more complex Data Models * Math on Step 9: Create more complex Data Models * Jonas G. on Step 15: Make an app that consumes your module * Pretzel on The Best external HDD for the Wii U is a High Endurance 256GB MicroSD card! * Landon on The Best external HDD for the Wii U is a High Endurance 256GB MicroSD card! ARCHIVES * April 2022 * March 2022 * December 2021 * December 2018 * January 2017 * November 2016 * May 2016 * February 2016 * November 2015 * September 2015 * August 2015 * May 2015 * April 2015 * March 2015 * February 2015 * January 2015 * November 2014 * October 2014 * September 2014 * August 2014 * February 2014 * January 2014 * March 2011 * February 2011 * January 2011 CATEGORIES * Analog * Cameras * Code * Digital * Main * Microcontrollers * Mobile * Networking * Power * Software * Storage * Uncategorized META * Log in * Entries feed * Comments feed * WordPress.org TAG CLOUD analog API Arduino BJT breadboard camera CCENT CCNA CD-R Cisco digital DIY Django DVD+R entry-level Flash drive flash memory GoPro HDD JSON laser LED LightScribe maker MOSFET Multimeter Netduino NVMe Portable Postman PWM Python Raspberry Pi REST SanDisk sd card SDK SJCAM SSD USB USB3 Video Wii Wii U XMP RECENT COMMENTS * Pretzel on Step 9: Create more complex Data Models * Math on Step 9: Create more complex Data Models * Jonas G. on Step 15: Make an app that consumes your module * Pretzel on The Best external HDD for the Wii U is a High Endurance 256GB MicroSD card! * Landon on The Best external HDD for the Wii U is a High Endurance 256GB MicroSD card! ARCHIVES * April 2022 * March 2022 * December 2021 * December 2018 * January 2017 * November 2016 * May 2016 * February 2016 * November 2015 * September 2015 * August 2015 * May 2015 * April 2015 * March 2015 * February 2015 * January 2015 * November 2014 * October 2014 * September 2014 * August 2014 * February 2014 * January 2014 * March 2011 * February 2011 * January 2011 RECENT POSTS * Step 15: Make an app that consumes your module * Step 14: Writing Unit Tests * Django ListView method execution order (and how to override) * Step 13: Paging the Endpoints * Step 12: Create more Endpoints and Helper Methods © 2024 Pretzel Logix Powered by WordPress To the top ↑ Up ↑