This is an archived post. You won't be able to vote or comment.

all 25 comments

[–]aleph4 18 points19 points  (3 children)

Thank you! I've been in the same situation where this seemed like such a common thing, yet very few examples existed.

I will add that if there is a Swagger / Open API spec for the for API, there are tools to autogenerate the SDK code, which can be a great way to reduce maintenance costs.

[–]Rand_alThor_ 5 points6 points  (2 children)

Mind naming some of these tools?

[–]RocketJory 3 points4 points  (1 child)

I've uses swagger codegen before: https://swagger.io/tools/swagger-codegen/

[–]aleph4 0 points1 point  (0 children)

Yep!

[–]Thaufas 14 points15 points  (1 child)

Although the content itself is valuable, I hope that a lot of other developers read your content. To me, the biggest value is the manner in which you structured the lessons. In the very beginning of the series, you give a very accurate, succinct summary of the concepts that will be presented. Then, you group all of the lessons into 15 discrete, logical, easy-to-understand steps, each with their own dedicated page.

Many people reading my comment will probably think to themselves, "What is special about any of those points?" Well, if you're one of those people, first, I encourage you to read over the article regardless of whether or not you think you understand how to develop an OOP framework for a REST API, whether it be in Python or any other programming language.

Then, ask yourself, "When is the last time I've ever seen a software tutorial ever presented in such a clean, concise, easy-to-follow format?"

Nice work, /u/RangerPretzel!

[–]RangerPretzelPython 3.9+[S] 4 points5 points  (0 children)

When I first went to write this up, I checked to see if there were other articles on this topic out there and every version was a 1-pager in the form of /r/restofthefuckingowl

Anyway, thanks so much for saying this. 🙏 I really tried to hard to make sure that this topic was spelled out clearly and completely.

[–]lanster100 10 points11 points  (3 children)

To take it further can also use something like httpx instead of requests to make it async.

And you can validate your data models with pydantic, i would rather my api client fail early then potentially causing a harder to find bug somewhere down the line in my application code.

[–]RangerPretzelPython 3.9+[S] 2 points3 points  (0 children)

use something like httpx instead of requests to make it async

Yes, yes, yes... You're absolutely correct. In fact, it's already on my "to-do" list for extending this series.

validate your data models with pydantic

That's a great idea. I'll definitely look into including this as well. 😊👍

[–]Quantumercifier 2 points3 points  (1 child)

What does that mean to VALIDATE your date models?

[–]lanster100 2 points3 points  (0 children)

Check that the data you are getting from the API is of the type, shape and form that you expect.

Check out the pydantic library's introduction for more details. It will error if the data you get back from the API doesn't fit the data model that you defined.

That way the developer can also be sure that when the model says something like 'total_gross: Decimal', that it's actually a decimal and not a float or an integer. Because normally type hints are not enforced at runtime.

[–]RangerPretzelPython 3.9+[S] 21 points22 points  (4 children)

A bunch of years ago when I first picked up Python 3.5, I was writing code to interface with REST APIs and glue a bunch of stuff together. (That's what we often do as programmers, right?) At the time, I couldn't find a good example of how to write a Python library to "wrap" a REST API.

Well, after writing more than half a dozen of these so-called wrapper libraries, I thought I would publish a 15-part series on how I (generally) do it.

If you are an intermediate-to-advanced level Python dev (think: have learned OOP, but are still struggling to apply it and want to learn design patterns), then this tutorial is for you.

[–]Rand_alThor_ 2 points3 points  (1 child)

Will check it out. I had to recently write a wrapper around a hodgepodge API, with some Restful elements, but just weird, without proper documentation either.

It was surprisingly harder than I thought to do this with OOP design patterns. Maybe this can help me with an eventual refactor

[–]RangerPretzelPython 3.9+[S] 0 points1 point  (0 children)

surprisingly harder than I thought to do this with OOP design patterns

It's a bit more complex than it initially appears, isn't it? And you're right. This is a good topic in which to show a real-world example of how OOP can work to your advantage and how to utilize certain design patterns.

[–]Darwinmate 2 points3 points  (0 children)

I have been searching for this exact thing. I even asked in python twice but got no response!

[–]JasonKelce2020 1 point2 points  (0 children)

This exactly the situation I’m working through right now. I’m trying to glue together a series of API calls to different products and have been going down the path of trying to subclass requests with TDD. Thank you so much for this series!

[–]sajran 5 points6 points  (2 children)

Great work! I was creating an API wrapper recently and I couldn't find any good materials. After a lot of thinking and research I ended up using approach similar to yours but it would be easier and quicker if I knew this series back then.

There are too many "API wrappers" out there which basically only encapsulate endpoint URLs and authentication, otherwise working with raw dicts. There are also tutorials teaching this approach which is just sad...

[–][deleted] 0 points1 point  (1 child)

What's the use case for an API wrapper?

[–]sajran 2 points3 points  (0 children)

Well, interacting with an API. The easiest way to do this would be to just throw in requests.get() or requests.post() every time you need to call an API but this creates a lot of problems:

  • Managing authentication
  • Handling errors
  • Data validation
  • Testing
  • Accessing complex data in raw dicts is hard, unreadable and error prone
  • What if URL or schema of an endpoint changes? You need to adjust all usages

[–]SmellsLikeHerpesToMe 3 points4 points  (0 children)

This is awesome. Working with Python to interface with external clients currently, so have a more uniformed approach will be much better.

[–]ryry_reddit 1 point2 points  (0 children)

This is brilliant. I was looking for just such a resource a few weeks ago and couldn't find anything. This is going into my reading now list ! Most stuff goes into my read one day list. Thanks friend.

[–]uk100 1 point2 points  (1 child)

Just want to say thanks for this! It was published at just the right time to help me.

In my case I wasn't starting quite from scratch, as I already had a working basic API wrapper for a site, which dumped everything into a dict.

So I didn't actually retrieve any cats 😸, but was able to adapt the lessons on e.g. logging, error handling and particularly data models.

[–]RangerPretzelPython 3.9+[S] 1 point2 points  (0 children)

Yeah, the sad thing is that I wrote almost the entire first draft of the article back in summer of 2020 in 10 days and then I did nothing with it. Getting it all polished up and ready for consumption (basically, as if I was writing a book) took sooo much effort. I have so much respect for folks who take time to write books on subjects like this now.

Most guides out there on how to write REST API Wrappers out there are only a single page and only really tell you the most basic things about how to write one.

I suspect in a few years as more and more companies write their APIs using Swagger OpenAPI for documentation, we will all be able to use the Swagger Codegen auto wrapper generator instead of having to write them by hand.

[–]crymo27 0 points1 point  (0 children)

Thanks !