<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Juan Benitez </title>
    <description>The latest articles on Forem by Juan Benitez  (@juanbenitezdev).</description>
    <link>https://forem.com/juanbenitezdev</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F133588%2Fe12a9749-63a9-482a-9de8-6ae5b6be86e8.jpg</url>
      <title>Forem: Juan Benitez </title>
      <link>https://forem.com/juanbenitezdev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/juanbenitezdev"/>
    <language>en</language>
    <item>
      <title>Best Python resources from beginner to advanced </title>
      <dc:creator>Juan Benitez </dc:creator>
      <pubDate>Mon, 03 Jan 2022 17:23:09 +0000</pubDate>
      <link>https://forem.com/juanbenitezdev/best-python-resources-from-beginner-to-advanced-c9a</link>
      <guid>https://forem.com/juanbenitezdev/best-python-resources-from-beginner-to-advanced-c9a</guid>
      <description>&lt;p&gt;Hey there, I made this compilation of websites, courses, youtube videos for learning Python.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Courses
&lt;/h2&gt;

&lt;p&gt;Couple of free courses to learn Python from scratch&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://youtu.be/_uQrJ0TkZlc"&gt;Python Tutorial&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/rfscVS0vtbw"&gt;Python Crash Course FreeCodeCamp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.edx.org/course/introduction-to-computer-science-and-programming-7"&gt;FREE MIT Course&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.geeksforgeeks.org/python-programming-language/"&gt;Geeks for Geeks&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. Algorithms and Data structures.
&lt;/h2&gt;

&lt;p&gt;Videos, texts, repositories about algorithms and data structures, &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://youtu.be/8hly31xKli0"&gt;Data structures and Algorithms&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.geeksforgeeks.org/fundamentals-of-algorithms/"&gt;Geeks for Geeks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bigocheatsheet.com/"&gt;BigO Cheat sheet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/tayllan/awesome-algorithms"&gt;GitHub Repo&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. Websites
&lt;/h2&gt;

&lt;p&gt;Websites all about Python&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.learnpython.org/"&gt;Learn Python&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://realpython.com/"&gt;Real Python&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.fullstackpython.com/"&gt;Full Stack Python&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://book.pythontips.com/en/latest/index.html"&gt;Python Tips&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://testdriven.io/guides/complete-python/"&gt;Test Driven&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  4. Web frameworks.
&lt;/h2&gt;

&lt;p&gt;Some of the best Python web frameworks&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.djangoproject.com/"&gt;Django&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://fastapi.tiangolo.com/"&gt;FastAPI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://palletsprojects.com/p/flask/"&gt;Flask&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/wsvincent/awesome-django"&gt;GitHub Repo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/juanbenitezdev/django-rest-framework-crud"&gt;GitHub Repo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/F5mRW0jo-U4"&gt;Django tutorial&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/Z1RJmh_OqeA"&gt;Flask Tutorial&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  5. Books
&lt;/h2&gt;

&lt;p&gt;For those who likes to read&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.packtpub.com/product/clean-code-in-python/9781788835831"&gt;Clean Code in Python&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.oreilly.com/library/view/python-cookbook-3rd/9781449357337/"&gt;Python CookBook&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.packtpub.com/product/expert-python-programming-fourth-edition/9781801071109"&gt;Expert Python Programming&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.feldroy.com/books/two-scoops-of-django-3-x"&gt;Two Scoops of Django 3.x&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  6. Advanced topics.
&lt;/h2&gt;

&lt;p&gt;Some advanced topics, from metaclasses to machine learning&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://youtu.be/cKPlPJyQrt4"&gt;Be a Python Expert&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/BRn6UCw35og"&gt;Python Advanced&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.freecodecamp.org/learn/machine-learning-with-python/"&gt;Machine Learning&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I hope you find helpful this list and can start your Python journey.&lt;/p&gt;

&lt;p&gt;You can follow me on &lt;a href="https://twitter.com/juanbenitezdev"&gt;Twitter&lt;/a&gt; and &lt;a href="https://github.com/juanbenitezdev"&gt;GitHub&lt;/a&gt; to be up to date with all my projects and content.&lt;/p&gt;

</description>
      <category>python</category>
      <category>webdev</category>
      <category>opensource</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Trending Python Projects of the week</title>
      <dc:creator>Juan Benitez </dc:creator>
      <pubDate>Thu, 30 Dec 2021 21:30:24 +0000</pubDate>
      <link>https://forem.com/juanbenitezdev/trending-python-projects-of-the-week-24j9</link>
      <guid>https://forem.com/juanbenitezdev/trending-python-projects-of-the-week-24j9</guid>
      <description>&lt;p&gt;I wanted to make a compilation of some of the nicest Python projects that have gained popularity on GitHub this week.&lt;/p&gt;

&lt;h2&gt;
  
  
  SQLModel
&lt;/h2&gt;

&lt;p&gt;As his creator defined, SQLModel is a Python library for interacting with SQL databases. It is based on Python type hints, and it uses &lt;a href="https://pydantic-docs.helpmanual.io/" rel="noopener noreferrer"&gt;Pydantic&lt;/a&gt; and &lt;a href="https://www.sqlalchemy.org/" rel="noopener noreferrer"&gt;SQLAlchemy&lt;/a&gt; internally. We can argue that SQLModel is just a layer on top of Pydantic and SQLAlchemy.&lt;/p&gt;

&lt;p&gt;SQLModel was created by the same person who created &lt;a href="https://fastapi.tiangolo.com/" rel="noopener noreferrer"&gt;FastAPI&lt;/a&gt;, so you can expect a pleasant and flawless integration between both.&lt;/p&gt;

&lt;p&gt;Although SQLModel was launched no more than 4 months ago (at the time of writing this), it already offers many features, and some others are already being developed, I encourage you to give it a try.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/tiangolo/sqlmodel" rel="noopener noreferrer"&gt;Github Repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://sqlmodel.tiangolo.com/" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Python Fire
&lt;/h2&gt;

&lt;p&gt;Python Fire is a library designed by Google for automatically generating command-line interfaces (CLIs) from absolutely any Python object, so basically you can create a Python method and generate a CLI from it.&lt;/p&gt;

&lt;p&gt;Here are some examples,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;fire&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;greeting&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;World&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello %s!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="n"&gt;fire&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Fire&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;greeting&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After import &lt;code&gt;fire&lt;/code&gt;, we can use it to generate a CLI from &lt;code&gt;greeting&lt;/code&gt; in this case.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;python&lt;/span&gt; &lt;span class="n"&gt;greeting&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;  &lt;span class="c1"&gt;# Hello World!
&lt;/span&gt;&lt;span class="n"&gt;python&lt;/span&gt; &lt;span class="n"&gt;greeting&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;Juan&lt;/span&gt;  &lt;span class="c1"&gt;# Hello Juan!
&lt;/span&gt;&lt;span class="n"&gt;python&lt;/span&gt; &lt;span class="n"&gt;greeting&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;help&lt;/span&gt;  &lt;span class="c1"&gt;# Shows usage information.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I think this library is really helpful for debugging, developing some Python scripts.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/google/python-fire" rel="noopener noreferrer"&gt;Github Repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/google/python-fire/blob/master/docs/using-cli.md" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you like to play with CLIs, you should try &lt;a href="https://github.com/tiangolo/typer" rel="noopener noreferrer"&gt;Typer&lt;/a&gt;, another great tool for building CLIs with Python.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sherlock
&lt;/h2&gt;

&lt;p&gt;This is simple, a Python script for searching usernames across several social networks, how cool is that huh?&lt;/p&gt;

&lt;p&gt;I tried with my username and there are some sites that I don’t know about, I should look into that…&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flkxdvpr6qt44l8fvcobb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flkxdvpr6qt44l8fvcobb.png" alt="sherlock"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/sherlock-project/sherlock" rel="noopener noreferrer"&gt;Github Repository&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  changedetection.io
&lt;/h2&gt;

&lt;p&gt;This is a tool for monitoring websites and get notifications when they change, so if you want to be on top of new information on the sites you like the most, give it a try. &lt;/p&gt;

&lt;p&gt;Some use cases for this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Governmental department updates (changes are often only on their websites)&lt;/li&gt;
&lt;li&gt;Products and services have a change in pricing&lt;/li&gt;
&lt;li&gt;New software releases, security advisories when you're not on their mailing list.&lt;/li&gt;
&lt;li&gt;Festivals with changes&lt;/li&gt;
&lt;li&gt;Real estate listing changes&lt;/li&gt;
&lt;li&gt;COVID-19 related news from government websites&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The best part about changedetection is that it is open source and you can self-host it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/dgtlmoon/changedetection.io" rel="noopener noreferrer"&gt;Github Repository&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I hope you like this list and leave a comment if you have used some of these tools or if you know about other Python projects gaining popularity.&lt;/p&gt;

&lt;p&gt;You can follow me on &lt;a href="https://www.twitter.com/juanbenitezdev" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; and &lt;a href="https://www.github.com/juanbenitezdev" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; to be up to date with all my projects and content.&lt;/p&gt;

</description>
      <category>python</category>
      <category>webdev</category>
      <category>programming</category>
      <category>opensource</category>
    </item>
    <item>
      <title>How to apply filters to images with Python</title>
      <dc:creator>Juan Benitez </dc:creator>
      <pubDate>Wed, 22 Dec 2021 00:01:44 +0000</pubDate>
      <link>https://forem.com/juanbenitezdev/how-to-apply-filters-to-images-with-python-3p8e</link>
      <guid>https://forem.com/juanbenitezdev/how-to-apply-filters-to-images-with-python-3p8e</guid>
      <description>&lt;p&gt;A few weeks ago, we received a new ticket: &lt;em&gt;“Users want to be able to apply filters to their pictures”&lt;/em&gt;, yes, something like Instagram does. We immediately thought about the Lightroom API, but after some research, we came to the conclusion that it doesn’t quite meet our needs. We were searching for something like a library, where we can just load the image, apply the filters and then save the new image with the filters applied, since we couldn’t find it we decided to build one.&lt;/p&gt;

&lt;h2&gt;
  
  
  FImage
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/jordandjp/fimage" rel="noopener noreferrer"&gt;FImage&lt;/a&gt;&lt;/strong&gt; is a Python module to apply and create multiple filters to images, it exposes an API that you can use for applying the different color transformations to the images. It works by converting the image to an RGB matrix and applying different math formulas to it. We used &lt;a href="https://numpy.org/" rel="noopener noreferrer"&gt;NumPy&lt;/a&gt; for all the matrix operations since it is faster and optimized, and &lt;a href="https://pillow.readthedocs.io/en/stable/" rel="noopener noreferrer"&gt;Pillow&lt;/a&gt; for handling the loading and saving of the images.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to use it?
&lt;/h2&gt;

&lt;p&gt;First, we need to install it, for this you need to be using Python 3.6 or greater to be able to use &lt;strong&gt;FImage&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;pip&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="n"&gt;fimage&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And for these examples, I’m gonna use this picture to apply it filters:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffjk44oa9ycowudgaf6fb.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffjk44oa9ycowudgaf6fb.jpg" alt="my_picture.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Applying a simple filter
&lt;/h3&gt;

&lt;p&gt;Create a file &lt;code&gt;app.py&lt;/code&gt; with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;fimage&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FImage&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;fimage.filters&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Sepia&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="c1"&gt;# replace 'my_picture.jpg' with the path to your image
&lt;/span&gt;    &lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;my_picture.jpg&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# apply the Sepia filter to the image
&lt;/span&gt;    &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Sepia&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="c1"&gt;# save the image with the applied filter
&lt;/span&gt;    &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;my_picture_sepia.jpg&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, just run it :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;python&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And this is how the new image &lt;code&gt;my_picture_sepia.jpg&lt;/code&gt; looks like after the filter was applied.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhjf09bxcipgbbjwuw9jv.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhjf09bxcipgbbjwuw9jv.jpg" alt="my_picture_sepia.jpg"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Applying multiple filters
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;FImage&lt;/strong&gt; offers more filters besides the Sepia one, even you can combine multiples filters to give a better look to your picture.&lt;/p&gt;

&lt;p&gt;Modify the file &lt;code&gt;app.py&lt;/code&gt; to import more filters from FImage&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;fimage&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FImage&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;fimage.filters&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Contrast&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Brightness&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Saturation&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;my_picture.jpg&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# apply the mutiple filters to the image
&lt;/span&gt;    &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nc"&gt;Saturation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="nc"&gt;Contrast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="nc"&gt;Brightness&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# save the image with the applied filter
&lt;/span&gt;    &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;my_picture_mixed.jpg&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We run it by&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;python&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And our new &lt;code&gt;my_picture_mixed.jpg&lt;/code&gt; looks like&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5i3tn210bvuyf8z7lqff.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5i3tn210bvuyf8z7lqff.jpg" alt="my_picture_mixed.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The order in which the filters are passed to the &lt;code&gt;apply&lt;/code&gt; function matters, this is because the filters are applied sequentially, so the next filter will be applied over the resultant image from the previous one.&lt;/p&gt;
&lt;h3&gt;
  
  
  Presets
&lt;/h3&gt;

&lt;p&gt;Presets are just the combinations of multiple filters with already defined adjustment values.&lt;/p&gt;

&lt;p&gt;Let’s change our &lt;code&gt;app.py&lt;/code&gt; one more time to use the Presets&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;fimage&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FImage&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;fimage.presets&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;SinCity&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="c1"&gt;# replace 'my_picture.jpg' with the path to your image
&lt;/span&gt;    &lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;my_picture.jpg&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# apply the SinCity preset to the image
&lt;/span&gt;    &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SinCity&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

    &lt;span class="c1"&gt;# save the image with the applied preset
&lt;/span&gt;    &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;my_picture_sincity.jpg&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After we run it, we get our new &lt;code&gt;my_picture_sincity.jpg&lt;/code&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv7e1azi4djosxguuq4r3.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv7e1azi4djosxguuq4r3.jpg" alt="my_picture_sincity.jpg"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Custom Presets
&lt;/h3&gt;

&lt;p&gt;If you like the look your picture got after testing different filters and want to store this combination for applying it to more pictures, you can create your own Preset by just extending the &lt;code&gt;Preset&lt;/code&gt; Class and specifying these filters and their adjust values in it.&lt;/p&gt;

&lt;p&gt;In our &lt;code&gt;app.py&lt;/code&gt; let’s do&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;fimage&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FImage&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;fimage.presets&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Preset&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;fimage.filters&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Contrast&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Brightness&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Saturation&lt;/span&gt;


&lt;span class="c1"&gt;# Create my custom preset and specify the filters to apply
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyOwnPreset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Preset&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;transformations&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="nc"&gt;Contrast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="nc"&gt;Saturation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="nc"&gt;Brightness&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="c1"&gt;# replace 'my_picture.jpg' with the path to your image
&lt;/span&gt;    &lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;my_picture.jpg&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# apply MyOwnPreset to the image
&lt;/span&gt;    &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MyOwnPreset&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

    &lt;span class="c1"&gt;# save the image with the applied preset
&lt;/span&gt;    &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;my_picture_custom.jpg&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The new &lt;code&gt;my_picture_custom.jpg&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmus16gejayn3a4i4ev1o.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmus16gejayn3a4i4ev1o.jpg" alt="my_picture_custom.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is basic usage of &lt;strong&gt;FImage&lt;/strong&gt;, we are still developing it, and it would be really great any feedback or contribution you have.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/jordandjp/fimage" rel="noopener noreferrer"&gt;GitHub Repo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can follow me on &lt;a href="https://www.twitter.com/juanbenitezdev" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; and &lt;a href="https://www.github.com/juanbenitezdev" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; to be up to date with all my projects and content.&lt;/p&gt;

</description>
      <category>python</category>
      <category>programming</category>
      <category>opensource</category>
      <category>showdev</category>
    </item>
    <item>
      <title>How to return DateTime in different time zones from Django Rest Framework</title>
      <dc:creator>Juan Benitez </dc:creator>
      <pubDate>Fri, 03 Sep 2021 01:09:59 +0000</pubDate>
      <link>https://forem.com/juanbenitezdev/how-to-return-datetime-in-different-time-zones-from-django-rest-framework-1396</link>
      <guid>https://forem.com/juanbenitezdev/how-to-return-datetime-in-different-time-zones-from-django-rest-framework-1396</guid>
      <description>&lt;p&gt;This is how we can return DateTimes with dynamic time zones from DRF.&lt;/p&gt;

&lt;p&gt;So, early this week I got a new ticket where I had to create new endpoints for our API, a few endpoints with DRF were not a big deal I said, this was until I realized that the DateTime values in the response from these endpoints needed to be converted from UTC to other time zones.&lt;/p&gt;

&lt;p&gt;We always store and return our DateTime values in UTC, and we convert them to the time zone of the user at display time, this can be in the browser using JS. But this time was different, the API needed to return the values in a specific time zone.&lt;/p&gt;

&lt;p&gt;We have something like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Venue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;time_zone&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;128&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'UTC'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;start_time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateTimeField&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;end_time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateTimeField&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;venue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ForeignKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Venue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;on_delete&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CASCADE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each Event is happening in a Venue, this venue is placed in some city, so we need to store the time zone used for that venue. Since we want to sell tickets or just promote some events we need to return the DateTime values in the venue time zone so we don't confuse the customers and other resellers.&lt;/p&gt;

&lt;p&gt;The first solution I thought of was the serializer field &lt;a href="https://www.django-rest-framework.org/api-guide/fields/#datetimefield"&gt;DateTimeField&lt;/a&gt;, it accepts an attribute called &lt;code&gt;default_timezone&lt;/code&gt;, this is a &lt;code&gt;pytz.timezone&lt;/code&gt; representing the timezone. If not specified and the &lt;code&gt;USE_TZ&lt;/code&gt; setting is enabled, this defaults to the current timezone. If &lt;code&gt;USE_TZ&lt;/code&gt; is disabled, then datetime objects will be naive.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EventSerializer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;serializers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ModelSerializer&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;start_time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;serializers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateTimeField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;default_timezone&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;pytz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;timezone&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'America/Bogota'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;end_time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;serializers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateTimeField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;default_timezone&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;pytz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;timezone&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'America/Bogota'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This works, if the &lt;code&gt;start_time&lt;/code&gt; in UTC is &lt;code&gt;2021-09-02T10:00:00&lt;/code&gt; in the resultant JSON will be displayed as &lt;code&gt;2021-09-02T05:00:00-05:00&lt;/code&gt;. But it didn't just work for me because I don't know the time zones beforehand and also they will be different, so I needed to do this at runtime, my solution was to override the &lt;code&gt;to_representation()&lt;/code&gt; method from the serializer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EventSerializer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;serializers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ModelSerializer&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;to_representation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'start_time'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;serializers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateTimeField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;default_timezone&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;pytz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;timezone&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;venue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;time_zone&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'end_time'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;serializers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateTimeField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;default_timezone&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;pytz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;timezone&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;venue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;time_zone&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;super&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;to_representation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;to_representation&lt;/code&gt; is run for each instance that is going to be returned by the serializer, so basically what we are doing is overriding the &lt;code&gt;start_time&lt;/code&gt; and &lt;code&gt;end_time&lt;/code&gt;  declaration for each instance, this is for specifying that we want to use a &lt;code&gt;DateTimeField&lt;/code&gt; and we want to pass it a &lt;code&gt;default_timezone&lt;/code&gt; which is going to be taken from the venue that is linked to the instance.&lt;/p&gt;

&lt;p&gt;This helped me to do what I needed and I hope that this can help you as well.&lt;/p&gt;

&lt;p&gt;You can follow me on &lt;a href="https://www.twitter.com/juanbenitezdev"&gt;Twitter&lt;/a&gt; and &lt;a href="https://www.github.com/juanbenitezdev"&gt;GitHub&lt;/a&gt; to be up to date with all my projects and content.&lt;/p&gt;

</description>
      <category>python</category>
      <category>programming</category>
      <category>django</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How to throttle your API with Django Rest Framework</title>
      <dc:creator>Juan Benitez </dc:creator>
      <pubDate>Sat, 28 Aug 2021 03:02:38 +0000</pubDate>
      <link>https://forem.com/juanbenitezdev/how-to-throttle-your-api-with-django-rest-framework-24oo</link>
      <guid>https://forem.com/juanbenitezdev/how-to-throttle-your-api-with-django-rest-framework-24oo</guid>
      <description>&lt;p&gt;Control the rate of requests that clients can make to your API.&lt;/p&gt;

&lt;h3&gt;
  
  
  But what is throttling...?
&lt;/h3&gt;

&lt;p&gt;As DRF says, throttling is &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Throttling is similar to permissions, in that it determines if a request should be authorized. Throttles indicate a temporary state, and are used to control the rate of requests that clients can make to an API&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In other words, we can say that throttling is a mechanism for limiting how many requests my API can accept in a period of time, we can specify this limit per user, IP address, etc. This is similar to how some APIs limit the number of requests you can make in a day or an hour.&lt;/p&gt;

&lt;h3&gt;
  
  
  How throttling is handle in DRF
&lt;/h3&gt;

&lt;p&gt;As with permissions and authentication, throttling in DRF is always defined as a list of classes.&lt;/p&gt;

&lt;p&gt;Before running the main body of the view each throttle in the list is checked. If any throttle check fails an &lt;code&gt;exceptions.Throttled&lt;/code&gt; exception will be raised, and the main body of the view will not run.&lt;/p&gt;

&lt;p&gt;And the same as permissions we can set these throttles globally and per views.&lt;/p&gt;

&lt;h4&gt;
  
  
  Global Throttles
&lt;/h4&gt;

&lt;p&gt;We can set a global default throttling policy using the &lt;code&gt;DEFAULT_THROTTLE_CLASSES&lt;/code&gt; and &lt;code&gt;DEFAULT_THROTTLE_RATES&lt;/code&gt; settings.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;REST_FRAMEWORK&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;'DEFAULT_THROTTLE_CLASSES'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s"&gt;'rest_framework.throttling.AnonRateThrottle'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;'rest_framework.throttling.UserRateThrottle'&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="s"&gt;'DEFAULT_THROTTLE_RATES'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;'anon'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'20/day'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;'user'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'50/day'&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;The rate descriptions used in &lt;code&gt;DEFAULT_THROTTLE_RATES&lt;/code&gt; may include &lt;code&gt;second&lt;/code&gt;, &lt;code&gt;minute&lt;/code&gt;, &lt;code&gt;hour&lt;/code&gt;, or &lt;code&gt;day&lt;/code&gt; as the throttle period.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;With these settings, &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Unauthenticated users will be able to only make 20 requests per day to our API, the IP address of the incoming request is used to generate a unique key to throttle against.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Authenticated users will be able to make 50 requests per day to our API, for these the id of the user is going to be used to generate the unique key.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When they reached the maximum of requests our API will respond with the error code  &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/429"&gt;&lt;em&gt;429 - Too Many Requests&lt;/em&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Since this is the global configuration this will apply to all views, but we can still override these settings per view.&lt;/p&gt;

&lt;h4&gt;
  
  
  Throttles Per View
&lt;/h4&gt;

&lt;p&gt;It's always better to have control over what views we want to limit, for this DRF offers us the possibility of setting these throttles classes per view.&lt;/p&gt;

&lt;p&gt;We do this by passing a list of throttles classes to the &lt;code&gt;throttle_classes&lt;/code&gt; attribute on the &lt;code&gt;APIView&lt;/code&gt; class-based views.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;rest_framework.response&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Response&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;rest_framework.throttling&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;UserRateThrottle&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;rest_framework.views&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;APIView&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ExampleView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;APIView&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;throttle_classes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;UserRateThrottle&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s"&gt;'status'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'request was permitted'&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this way, &lt;code&gt;ExampleView&lt;/code&gt; will use the &lt;code&gt;UserRateThrottle&lt;/code&gt; class to limit the number of requests that this view can receive, the rates, in this case, are still defined on the &lt;code&gt;DEFAULT_THROTTLE_CLASSES&lt;/code&gt; settings key.&lt;/p&gt;

&lt;p&gt;But what if we want to specify a different rate for a specific view, we can do this by extending the &lt;code&gt;UserRateThrottle&lt;/code&gt; class and specifying a new rate.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;rest_framework.response&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Response&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;rest_framework.throttling&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;UserRateThrottle&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;rest_framework.views&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;APIView&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CustomUserRateThrottle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UserRateThrottle&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;rate&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'5/day'&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;VeryLimitedView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;APIView&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;throttle_classes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;CustomUserRateThrottle&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s"&gt;'status'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'request was permitted'&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now &lt;strong&gt;only&lt;/strong&gt; for this view the authenticated users have 5 requests per day, even though the global settings say that the users have 50 requests per day.&lt;/p&gt;

&lt;h4&gt;
  
  
  ScopedRateThrottles
&lt;/h4&gt;

&lt;p&gt;The &lt;code&gt;ScopedRateThrottle&lt;/code&gt; class can be used to restrict access to specific parts of the API. This throttle will only be applied if the view that is being accessed includes a &lt;code&gt;.throttle_scope&lt;/code&gt; attribute.&lt;/p&gt;

&lt;p&gt;The allowed request rate is determined by the &lt;code&gt;DEFAULT_THROTTLE_RATES&lt;/code&gt; setting using a key from the request &lt;em&gt;"scope"&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;For example, given the following views...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ContactListView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;APIView&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;throttle_scope&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'contacts'&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ContactDetailView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;APIView&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;throttle_scope&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'contacts'&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UploadView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;APIView&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;throttle_scope&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'uploads'&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...and the following settings.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;REST_FRAMEWORK&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;'DEFAULT_THROTTLE_CLASSES'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s"&gt;'rest_framework.throttling.ScopedRateThrottle'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="s"&gt;'DEFAULT_THROTTLE_RATES'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;'contacts'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'100/day'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;'uploads'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'50/day'&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;User requests to either &lt;code&gt;ContactListView&lt;/code&gt; or &lt;code&gt;ContactDetailView&lt;/code&gt; would be restricted to a total of 100 requests per day. User requests to &lt;code&gt;UploadView&lt;/code&gt; would be restricted to 50 requests per day.&lt;/p&gt;

&lt;h3&gt;
  
  
  So, what's next...
&lt;/h3&gt;

&lt;p&gt;As we saw, throttles is a powerful and really helpful feature that we can implement on our API if we need to impose different constraints on different parts of the API, due to some services being particularly resource-intensive. Also, it's worth mentioning that DRF provides a &lt;code&gt;BaseThrottle&lt;/code&gt; class which you can override to create custom throttles with custom implementations.&lt;/p&gt;

&lt;p&gt;If you plan to use this method as a security feature just consider that the DRF throttling isn't intended as a security feature, it has some &lt;a href="https://github.com/encode/django-rest-framework/issues/8127"&gt;weaknesses&lt;/a&gt;  and you shouldn't rely only upon the throttling. &lt;/p&gt;

&lt;p&gt;Yet, it's a cool feature and you should definitely try it on your API.&lt;/p&gt;

&lt;p&gt;You can follow me on &lt;a href="https://www.twitter.com/juanbenitezdev"&gt;Twitter&lt;/a&gt; and &lt;a href="https://www.github.com/juanbenitezdev"&gt;GitHub&lt;/a&gt; to be up to date with all my projects and content.&lt;/p&gt;

</description>
      <category>python</category>
      <category>django</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>My First FastAPI Experience</title>
      <dc:creator>Juan Benitez </dc:creator>
      <pubDate>Thu, 26 Aug 2021 17:52:29 +0000</pubDate>
      <link>https://forem.com/juanbenitezdev/my-first-fastapi-experience-4ioh</link>
      <guid>https://forem.com/juanbenitezdev/my-first-fastapi-experience-4ioh</guid>
      <description>&lt;p&gt;A few weeks ago I started my journey with &lt;a href="https://fastapi.tiangolo.com/"&gt;FastAPI&lt;/a&gt; a modern, fast web framework, this is how his creator defines it.&lt;/p&gt;

&lt;p&gt;I heard about FastAPI a long time ago when some coworker told me that this framework was built by a Colombian, I'm from Colombia as well so I was really curious about it, anyway I didn't pay too much attention to it at first because I was really focused on learning Django.&lt;br&gt;
But now when I feel like I have a certain level of expertise in Django I wanted to give it a try.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where I started?
&lt;/h2&gt;

&lt;p&gt;I started at the docs as usual and I thought at first, well this is pretty much Flask but with async support. But obviously, it wasn't just that.&lt;/p&gt;

&lt;p&gt;While I was reading the docs I was always trying to make comparisons with Django Rest Framework, even though these are completely different web frameworks, this helped me to better understand what I was reading and why I should use one over the other.&lt;/p&gt;

&lt;h2&gt;
  
  
  Django and FastAPI
&lt;/h2&gt;

&lt;p&gt;The first comparison I made was serializers and Pydantic, these both can be used to validate the data you are passing in the request and to serialize your objects but the big difference comes when Pydantic benefits from the Python type hints, so you don't learn extra syntax, and this type hints fit perfectly with the IDEs, so you have autocompletion and all those nice features.&lt;/p&gt;

&lt;p&gt;The second thing that I wanted to check was the views, these guys that are in charge of taking the request and returning a response. DRF provides many options when it comes to views, it has generic classes, viewsets, mixins, etc. FastApi on the other hand has something they call path operation function, this is a function that is related to a path and it's going to be executed when this path is requested. First, I was confused because it can be hard to understand how this functions works, for example, if you pass a parameter to this function this is going to be treated as a query parameter but you also define the path parameter there, and also the body is passed as a parameter, so you need to define this parameter with special types provided by FastAPI so it knows how to treat every parameter.&lt;br&gt;
Please, I know this sounds confusing but when you understand it, it is pretty simple. I have to be honest and I kind of like the DRF Class views more, it just seems more organized and simple at least for me. Yet, you can organize and share code along with the application, they have something called Dependencies that is used for this, it's worth taking a look at it because it's a really powerful feature.&lt;/p&gt;

&lt;p&gt;The last thing I want to mention and that is the async support, this is just great, it comes with the framework so we don't need to configure or install something else. And the same goes for automatic documentation, every time you create a new endpoint the docs for this endpoint are created automatically using all the different things you defined for that endpoint, query parameters, path parameters, body requests, responses, authentication, etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is next?
&lt;/h2&gt;

&lt;p&gt;I'm really excited about this journey, I'm already doing some projects with FastApi and I hope I can tell you soon about it.&lt;/p&gt;

&lt;p&gt;Also, I'm contributing to translate the docs to Spanish, this has helped me a lot as well because in this way I can read really carefully all the things that the framework provides.&lt;/p&gt;

&lt;p&gt;I hope this can help you as well, and if you have any questions please don't hesitate, and of course check FastApi, it's really powerful and nice to learn.&lt;/p&gt;

</description>
      <category>python</category>
      <category>django</category>
      <category>fastapi</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Simple tweet locator using Python, Flask SocketIO and Tweepy</title>
      <dc:creator>Juan Benitez </dc:creator>
      <pubDate>Sat, 14 Mar 2020 20:27:56 +0000</pubDate>
      <link>https://forem.com/juanbenitezdev/simple-tweet-locator-using-python-flask-socketio-and-tweepy-49p5</link>
      <guid>https://forem.com/juanbenitezdev/simple-tweet-locator-using-python-flask-socketio-and-tweepy-49p5</guid>
      <description>&lt;p&gt;Simple application to locate tweets on a map based on the location from where they were sent.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PWprR-KL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/6ow4y71a6na5cn0m8sqg.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PWprR-KL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/6ow4y71a6na5cn0m8sqg.gif" alt="Alt Text" width="600" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This application was written in &lt;a href="https://www.python.org/"&gt;Python 3.7&lt;/a&gt;, and uses &lt;a href="https://flask-socketio.readthedocs.io/en/latest/"&gt;Flask Socket IO&lt;/a&gt; which gives Flask applications access to low latency bi-directional communications between the clients and the server, and &lt;a href="https://www.tweepy.org/"&gt;Tweepy&lt;/a&gt; a Python-based client to interact with the Twitter REST APIs.&lt;/p&gt;

&lt;p&gt;In order to have access to Twitter data programmatically it's necessary to have some access tokens, you can create an app and get your secret tokens from &lt;a href="https://developer.twitter.com/en/apps"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;The full source code can be found on &lt;a href="https://github.com/JuanBenitez97/Tweet-Locator"&gt;Github&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone https://github.com/JuanBenitez97/Tweet-Locator.git
cd Tweet-Locator
pip install -r requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After this proccess is done you need to create a &lt;strong&gt;.env&lt;/strong&gt; file to store all your secret tokens and being able to use the Twitter APIs, this file should be in the root folder.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CONSUMER_KEY = 'Your API KEY'
CONSUMER_SECRET = 'Your API SECRET KEY'
ACCESS_TOKEN = 'Your Access Token'
ACCESS_SECRET = 'Your Access Secret Token'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Run
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;python app.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If everything is correct you will see the server is running and which host and port is running on.&lt;br&gt;
Just go to the url and wait for the tweets appear on the map.&lt;/p&gt;

&lt;p&gt;If you want to filter tweets based on other words you can change the tags in the &lt;strong&gt;app.py&lt;/strong&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if __name__ == '__main__':
    """
    tags = ["#python", "programming", "flask"]   
    """
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--A0c4ajpJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/v1/media/tweetlocator.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A0c4ajpJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/v1/media/tweetlocator.gif" alt="" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Enjoy it!!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>flask</category>
      <category>sockets</category>
      <category>tweepy</category>
    </item>
  </channel>
</rss>
