<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Tech Blog By Faris]]></title><description><![CDATA[Technologist, Entrepreneur]]></description><link>https://blog.farismohamed.me</link><generator>RSS for Node</generator><lastBuildDate>Tue, 12 May 2026 17:50:20 GMT</lastBuildDate><atom:link href="https://blog.farismohamed.me/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[The world of Medical Imaging Technology]]></title><description><![CDATA[Starting Point: Complete Domain Unfamiliarity
The project began as an R&D initiative to build a proof-of-concept for a medical imaging AI orchestration platform. The technical brief mentioned Mercure and MONAI as core technologies. On paper, it appea...]]></description><link>https://blog.farismohamed.me/the-world-of-medical-imaging-technology</link><guid isPermaLink="true">https://blog.farismohamed.me/the-world-of-medical-imaging-technology</guid><category><![CDATA[monai]]></category><category><![CDATA[dicom]]></category><category><![CDATA[medical]]></category><category><![CDATA[AI]]></category><category><![CDATA[Mercure]]></category><dc:creator><![CDATA[Faris Mohamed]]></dc:creator><pubDate>Thu, 31 Jul 2025 02:15:40 GMT</pubDate><content:encoded><![CDATA[<hr />
<h2 id="heading-starting-point-complete-domain-unfamiliarity">Starting Point: Complete Domain Unfamiliarity</h2>
<p>The project began as an R&amp;D initiative to build a proof-of-concept for a medical imaging AI orchestration platform. The technical brief mentioned <a target="_blank" href="https://mercure-imaging.org/docs/intro.html">Mercure</a> and <a target="_blank" href="https://monai.io/">MONAI</a> as core technologies. On paper, it appeared to be a standard development project.</p>
<p>The reality was far more complex.</p>
<p>Coming into this project with no previous exposure to medical imaging, the domain presented immediate challenges. The first hurdle wasn't architectural or technical—it was understanding the fundamental terminologies. What exactly is a "lesion"? MS lesions, as it turns out, are areas of damage or scarring in the central nervous system associated with Multiple Sclerosis. These small spots visible on brain scans carry critical diagnostic significance that wasn't immediately obvious to someone outside the medical field.</p>
<h2 id="heading-understanding-dicom">Understanding DICOM</h2>
<p>The first major technical challenge was understanding DICOM—the Digital Imaging and Communications in Medicine standard. Initial research led to several key resources, including the "<a target="_blank" href="https://dicomiseasy.blogspot.com/2011/10/introduction-to-dicom-chapter-1.html?m=1">Introduction to DICOM</a>" blog series, <a target="_blank" href="https://pydicom.github.io/">PyDICOM</a> documentation, and the official <a target="_blank" href="https://dicom.nema.org/medical/dicom/current/output/html/part01.html">DICOM standard documentation from NEMA</a>. These resources revealed that medical images aren't simple picture files; they're complex data structures containing patient information, acquisition parameters, and metadata crucial for diagnosis.</p>
<p>Working with DICOM files programmatically using PyDICOM showed the difference between medical imaging and conventional image formats. Unlike JPEG or PNG files, DICOM files carry everything from pixel data to patient demographics, study descriptions, and technical parameters. Each DICOM file contains hundreds of tags, each serving a specific purpose in the medical workflow.</p>
<p>Understanding the structure took considerable time. ContentSequence tags, Structured Reports, Study Instance UIDs—terms that initially appeared as technical jargon but gradually revealed their significance in the medical imaging ecosystem. The complexity of DICOM becomes apparent when you realize it's not just an image format, but a comprehensive standard for medical image communication and storage.</p>
<h2 id="heading-workflow-orchestration-with-mercure">Workflow Orchestration with Mercure</h2>
<p>Mercure served as the introduction to medical imaging workflows and orchestration. The initial setup involved configuring Amazon EC2 instances, managing Docker containers, and understanding how different components communicate in a hospital environment.</p>
<p>Mercure's role extends beyond simple image processing—it manages complex workflows. When a DICOM study arrives, Mercure can automatically trigger AI analysis, route results to different systems, and generate reports while maintaining the strict standards required in healthcare.</p>
<p>The infrastructure setup included working with dcmsend commands and managing the 60-second reception timeout, which makes sense when you understand that medical studies often consist of hundreds of images that need to be received completely before processing can begin.</p>
<h2 id="heading-dicom-server-infrastructure">DICOM Server Infrastructure</h2>
<p>Initial research into DICOM server solutions led to evaluating Orthanc, a lightweight DICOM server. However, for our specific requirements, Orthanc seemed heavy-handed given our minimal use case and the need for tight integration with our existing database and backend technology stack.</p>
<p>Instead, we built a custom DICOM server using <a target="_blank" href="https://pydicom.github.io/pynetdicom/stable/">pynetdicom</a>. This approach provided several advantages: direct integration with our database architecture, alignment with our backend technology stack, and precise control over the DICOM operations we needed to support.</p>
<p>The pynetdicom library offered the flexibility to implement exactly the DICOM services required without the overhead of a full-featured server like Orthanc. This custom implementation allowed seamless integration with our workflow orchestration and maintained the critical data integrity standards essential in medical imaging, where every pixel matters for radiological diagnosis.</p>
<h2 id="heading-medical-image-viewing-and-custom-development">Medical Image Viewing and Custom Development</h2>
<p>Working with OHIF (Open Health Imaging Foundation) and Cornerstone provided the foundation for understanding medical image visualization. These platforms demonstrated the sophistication required for medical image interpretation beyond simple image display.</p>
<p>Cornerstone's rendering capabilities highlighted the complexity of medical image display. Windowing and leveling, which adjust brightness and contrast to highlight specific tissue types, became essential concepts.</p>
<p>Our specific requirements for lesion tracking led to the development of a custom solution from scratch. After evaluating OHIF's customization capabilities, it became clear that achieving the precise lesion tracking functionality needed would require building a custom lesion tracker rather than adapting existing OHIF components.</p>
<p>The custom lesion tracker development involved working directly with Cornerstone's rendering engine while building specialized tools for MS lesion identification, measurement, and tracking across multiple time points. This approach provided the granular control necessary for the specific clinical workflow requirements.</p>
<h2 id="heading-medical-ai-with-open-source"><strong>Medical AI with Open Source</strong></h2>
<p>Open source frameworks have transformed medical imaging AI by providing specialized tools for healthcare's unique challenges. MONAI's comprehensive framework, TotalSegmentator for automated organ segmentation, and the MONAI Model Zoo's pre-trained models eliminate the need to build from scratch while ensuring clinical-grade quality.</p>
<p>Medical AI demands more than accuracy—it requires reliability and interpretability. A false positive in tumor detection can lead to patient anxiety and unnecessary procedures. Open source medical AI tools address these stakes through robust validation, standardized pipelines, and transparent architectures that clinicians can understand and trust.</p>
<p>This ecosystem accelerates innovation while maintaining the rigorous standards essential for healthcare applications.</p>
<h2 id="heading-domain-knowledge-acquisition">Domain Knowledge Acquisition</h2>
<p>The technical learning curve was paralleled by necessary medical domain knowledge acquisition. Understanding medical terminology became essential for effective platform development. Axial, sagittal, and coronal views became standard concepts, along with understanding why certain imaging protocols exist and how different modalities—CT, MRI, PET—serve different diagnostic purposes.</p>
<p>The learning process involved understanding why DICOM Structured Reports exist, how to generate PDF reports that integrate with hospital workflows, and ensuring that AI-generated insights are presented in formats that clinicians can trust and act upon.</p>
<h2 id="heading-systems-integration-perspective">Systems Integration Perspective</h2>
<p>The most significant realization was that medical imaging isn't about individual technologies—it's about integrated ecosystems. Mercure orchestrating workflows, MONAI providing AI capabilities, OHIF and custom viewers enabling visualization, and DICOM ensuring interoperability. Each component serves a critical role in delivering patient care.</p>
<p>The initial technical challenges—DICOM tag complexity, medical terminology, strict data handling requirements—all served purposes within a larger system designed to support healthcare delivery.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>This project demonstrated that building for healthcare requires accepting higher standards of responsibility. Every technical decision potentially impacts patient outcomes, requiring a different approach to software development than typical commercial applications.</p>
<p>The complexity that initially presented significant challenges—from understanding MS lesions to configuring AI orchestration pipelines—provided appreciation for the sophisticated systems supporting modern medicine.</p>
<p>Medical imaging technology operates at the intersection of advanced AI, complex data management, and life-critical decision making. It's a domain where technical excellence extends beyond performance metrics to enabling better patient care.</p>
<p>For technical professionals considering healthcare technology, the domain knowledge requirements are substantial, but the potential impact is significant. Every successful DICOM transfer, accurate AI prediction, and properly rendered medical image contributes to systems that improve patient outcomes.</p>
<p>The complexity exists for important reasons, and mastering it enables meaningful contributions to healthcare technology advancement.</p>
<hr />
<p><em>This write-up is a future reference to myself and to anyone who’s getting started with the development of a medical imaging platform.</em></p>
]]></content:encoded></item><item><title><![CDATA[A Comprehensive Guide to Migrating your apps to the Latest React Native Version]]></title><description><![CDATA[React Native, a powerful framework for building cross-platform mobile applications continues to evolve rapidly, introducing new features, bug fixes, and performance enhancements with each new version. Staying up to date with the latest version of Rea...]]></description><link>https://blog.farismohamed.me/react-native-version-migration-guide</link><guid isPermaLink="true">https://blog.farismohamed.me/react-native-version-migration-guide</guid><category><![CDATA[React Native]]></category><category><![CDATA[technology]]></category><category><![CDATA[optimization]]></category><category><![CDATA[performance]]></category><dc:creator><![CDATA[Faris Mohamed]]></dc:creator><pubDate>Fri, 04 Aug 2023 12:50:08 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1691151819268/a5882321-4525-4a4d-b5d5-39230cd1d91f.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>React Native, a powerful framework for building cross-platform mobile applications continues to evolve rapidly, introducing new features, bug fixes, and performance enhancements with each new version. Staying up to date with the latest version of React Native is essential to ensure your app benefits from these improvements. However, upgrading or migrating to a new version can be a daunting task, especially if you're dealing with a large codebase or heavily relying on third-party libraries. In this blog post, I'll walk you through the best practices of upgrading an app to the latest version of React Native, helping you make a smooth transition while minimizing potential issues. My team at <a target="_blank" href="https://bytsolv.com">Bytsolv</a> has been working on multiple migrations lately and every app came with its own challenges, so documenting them would be beneficial for the community and even future us.</p>
<h2 id="heading-assessing-your-current-state"><strong>Assessing Your Current State</strong></h2>
<p>Before initiating the upgrade process, it's crucial to assess your current project. Identify the version of React Native you're currently using and research the features and improvements introduced in subsequent versions. This will help you understand the benefits and potential challenges you might encounter during the upgrade, and evaluate if the upgrade is worth the effort.</p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">Tip: Utilize the <a target="_blank" href="https://react-native-community.github.io/upgrade-helper/">React Native Upgrade Helper</a> to simplify the upgrade process and easily identify the changes between versions, ensuring a smoother transition for your project.</div>
</div>

<h2 id="heading-planning-and-preparation"><strong>Planning and Preparation</strong></h2>
<p><strong>Review the release notes</strong>: Thoroughly examine the release notes for the versions between your current version and the latest release to understand the changes and potential impacts on your codebase.</p>
<p><strong>Update dependencies</strong>: Check if third-party libraries and dependencies are compatible with the new React Native version and update them to their latest versions for compatibility and improvements.</p>
<p><strong>Backup your project</strong>: Create a backup of your project to protect against any unforeseen issues during the upgrade process. For instance, create a backup branch in git and store your current version of the app there, and start working on the upgrades in a new branch.</p>
<p><strong>Prepare a test plan</strong>: Develop a comprehensive test plan to ensure all features and scenarios are thoroughly tested, covering different devices, operating systems, and screen sizes.</p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">If your app is in continuous development, It is recommended to stop further developments while performing the migrations. It won't be possible for all the teams, so in that case, have a plan to track and sync the migration and developments side by side.</div>
</div>

<h2 id="heading-the-touchpoints">The Touchpoints</h2>
<ol>
<li><p><strong>Core Native Code and Third-Party Libraries</strong>: Update native modules, Java/Kotlin (for Android), Objective-C/Swift (for iOS), and third-party libraries to ensure compatibility with the upgraded React Native version.</p>
</li>
<li><p><strong>JavaScript APIs, Syntax, and UI Components</strong>: Adjust JavaScript APIs, syntax, and UI components to comply with the new version's standards and incorporate any changes introduced in the upgraded React Native version.</p>
</li>
<li><p><strong>React Native CLI and Tooling, Package Managers</strong>: Review and update the React Native CLI, associated tooling, and package managers (e.g., npm, Yarn) to maintain compatibility with the new version.</p>
</li>
<li><p><strong>Platform-Specific Code and Device Compatibility</strong>: Adapt platform-specific code blocks and thoroughly test the app on various devices and operating system versions to identify and resolve compatibility issues.</p>
</li>
<li><p><strong>App State Management and Performance Optimization</strong>: Verify compatibility of the state management solution (e.g., Redux, MobX) and leverage performance optimizations introduced in the upgraded React Native version to enhance app performance.</p>
</li>
</ol>
<h2 id="heading-start-small-go-incremental">Start Small, Go Incremental</h2>
<p>Starting with a small module and using an incremental approach can significantly simplify the upgrade process. Here are more ideas on how to implement this approach effectively:</p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">If possible create a checklist for all the modules available in the project and go by checking them one by one while upgrading. It'll be helpful to keep track and not miss any modules.</div>
</div>

<ol>
<li><p><strong>Start Small and Isolated</strong>: Begin by selecting a specific module or feature within your app to upgrade first. Create a dedicated branch for the upgrade process.</p>
</li>
<li><p><strong>Update Dependencies</strong>: Start by updating relevant dependencies and third-party libraries used in the selected module.</p>
</li>
<li><p><strong>Upgrade React Native Incrementally</strong>: Gradually upgrade the React Native version in the isolated branch, ensuring compatibility with the new version.</p>
</li>
<li><p><strong>Test and Validate</strong>: Thoroughly test the upgraded module to identify and fix any issues. Perform comprehensive testing on various devices and platforms.</p>
</li>
<li><p><strong>Review, Refactor, and Optimize</strong>: Take the opportunity to review the code, refactor as needed, and implement any performance optimizations.</p>
</li>
<li><p><strong>Merge Changes Incrementally</strong>: After successful testing, merge the upgraded module back into the main codebase.</p>
</li>
<li><p><strong>Repeat for Other Modules</strong>: Continue this incremental upgrade approach with other isolated modules or features, one at a time.</p>
</li>
</ol>
<h2 id="heading-handling-compatibility-issues-andamp-breaking-changes">Handling Compatibility Issues &amp; Breaking Changes</h2>
<p>React Native upgrades often come with compatibility issues and breaking changes that can impact your app's functionality. Some issues I've faced during the upgrades and the solutions I implemented are documented below:</p>
<ol>
<li><p><strong>Deprecation and Removal of APIs</strong>: Address changes to existing APIs that are deprecated or removed in the upgraded React Native version.</p>
</li>
<li><p><strong>Third-Party Library Compatibility</strong>: Check compatibility with third-party libraries and update them to work with the new React Native version.</p>
</li>
<li><p><strong>Native Modules and Dependencies</strong>: Update custom native modules and dependencies to ensure compatibility with the upgraded React Native version.</p>
</li>
<li><p><strong>Behavioral Changes in Components</strong>: Adjust components and modules affected by changes in behavior or props.</p>
</li>
<li><p><strong>File Structure and Naming</strong>: Accommodate any changes to the folder structure or file naming conventions introduced in the new version.</p>
</li>
<li><p><strong>Animation and Interaction Modifications</strong>: Handle modifications in animations, gestures, and keyboard interactions due to the React Native upgrade.</p>
</li>
</ol>
<h2 id="heading-community-collaboration">Community Collaboration</h2>
<p>Engaging with the community is really essential for all kinds of developers. Community forums, repositories, and blogs offer valuable guidance, solutions, and collective knowledge to overcome compatibility challenges and breaking changes effectively. By actively participating in discussions and accessing official documentation, developers stay informed about best practices, ensuring smoother upgrade journeys.</p>
<p>Giving back to the community is equally vital. Sharing upgrade experiences, writing blogs, and contributing to discussions strengthens the community and enables others to navigate upgrades more successfully. The culture of mutual support and continuous improvement empowers developers to optimize their workflows while enhancing the growth and success of the entire React Native community.</p>
<h2 id="heading-concluding">Concluding...</h2>
<p>Commencing a React Native version upgrade requires meticulous assessment and thoughtful planning. Through careful evaluation of your app's current state and strategic preparation, you lay a solid foundation for a successful upgrade process. As you progress, identifying touchpoints like core native code, third-party libraries, and custom modules becomes pivotal. Incremental adaptation minimizes compatibility issues and breaking changes, ensuring a smoother transition.</p>
<p>Handling compatibility challenges and breaking changes demands a strategic approach. Keeping a keen eye on deprecated APIs, ensuring third-party library compatibility, and updating custom native modules are essential steps to ensure a seamless transition. Throughout the upgrade journey, the React Native community becomes a valuable asset. Engaging with forums, repositories, and webinars offers access to collective knowledge and shared expertise while contributing back empowers the community and fostering a supportive ecosystem.</p>
<p>By staying updated, developers position their apps for future growth and security in a rapidly evolving mobile landscape. In conclusion, as you set forth on your React Native upgrade journey, assess, strategize, collaborate, and embrace the advantages of the latest version. This approach paves the way for a smoother, more rewarding upgrade experience, leading to a more powerful, innovative, and successful mobile application.</p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">🚀</div>
<div data-node-type="callout-text">If you have a React native app that needs to be upgraded or you are stuck while you are trying to upgrade, feel free to get in touch with the <a target="_blank" href="https://bytsolv.com">Bytsolv</a> team.</div>
</div>

<h2 id="heading-references-and-acknowledgements">References and Acknowledgements</h2>
<ul>
<li><p><a target="_blank" href="https://react-native-community.github.io/upgrade-helper/">https://react-native-community.github.io/upgrade-helper/</a></p>
</li>
<li><p><a target="_blank" href="https://reactnative.dev/docs/upgrading">https://reactnative.dev/docs/upgrading</a></p>
</li>
<li><p><a target="_blank" href="https://medium.com/game-development-stuff/how-to-easily-upgrade-react-native-and-the-project-dependencies-6af458ada81c">https://medium.com/game-development-stuff/how-to-easily-upgrade-react-native-and-the-project-dependencies-6af458ada81c</a></p>
</li>
<li><p>Thanks <a target="_blank" href="https://www.behance.net/qhaasi">Anas</a> for the thumbnail ❤️.</p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[The Fundamentals of API Security: How to Keep Your APIs Safe and Secure]]></title><description><![CDATA[In today's digital age, APIs are a critical component of web applications. They allow different systems to communicate with each other, making it possible for developers to create complex and innovative applications. However, with this increased conn...]]></description><link>https://blog.farismohamed.me/fundamentals-of-api-security</link><guid isPermaLink="true">https://blog.farismohamed.me/fundamentals-of-api-security</guid><category><![CDATA[APIs]]></category><category><![CDATA[Security]]></category><category><![CDATA[vulnerability]]></category><category><![CDATA[api security]]></category><dc:creator><![CDATA[Faris Mohamed]]></dc:creator><pubDate>Mon, 03 Apr 2023 03:47:03 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1637514140700/MDOzboBR8.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In today's digital age, APIs are a critical component of web applications. They allow different systems to communicate with each other, making it possible for developers to create complex and innovative applications. However, with this increased connectivity comes increased risk. According to recent studies, over 80% of cyber attacks now target APIs, making API security more important than ever before. APIs may have vulnerabilities like broken authentication and authorization, lack of rate limiting, and code injection. In this post, we'll look at some of the measures and best practices you can follow to develop secure APIs and protect your data from potential threats.</p>
<h1 id="heading-authentication">Authentication</h1>
<p>To ensure that applications and clients trying to access data are authentic, APIs must be equipped with a process to certify the identity of users trying to access resources on the server. This is what is known as API authentication. There are several authentication methods that can be used to secure APIs, including:</p>
<ul>
<li><p><strong>OAuth:</strong> a protocol that enables applications to authenticate and authorize access to APIs on behalf of users.</p>
</li>
<li><p><strong>API Key Authentication:</strong> a method where a unique key is generated for each user and used to authenticate API requests.</p>
</li>
<li><p><strong>JSON Web Token (JWT):</strong> a compact, URL-safe means of representing claims to be transferred between parties.</p>
</li>
<li><p><strong>User-based Authentication:</strong> a method where each user has a unique username and password to authenticate API requests.</p>
</li>
<li><p><strong>SAML:</strong> An open standard for exchanging authentication and authorization data between parties, often used for single sign-on (SSO).</p>
</li>
<li><p><strong>OpenID Connect:</strong> A protocol built on OAuth 2.0 for standardized user authentication and identity information exchange.</p>
</li>
<li><p><strong>LDAP:</strong> A protocol for accessing and maintaining directory information services over a network, often used for authentication and authorization in enterprise applications.</p>
</li>
</ul>
<h1 id="heading-authorization">Authorization</h1>
<p>Authorization is the next step after successful authentication. It is the process of granting or denying access to a specific resource based on the authenticated user's identity and level of permission. Some common methods of authorization include:</p>
<ul>
<li><p><strong>Role-based access control (RBAC):</strong> a method that restricts access based on the roles that users have within the system.</p>
</li>
<li><p><strong>Attribute-based access control (ABAC):</strong> a method that grants access based on specific attributes or characteristics of the user.</p>
</li>
<li><p><strong>Access Control Lists (ACL):</strong> a list that contains rules that grant or deny access to specific entities.</p>
</li>
<li><p><strong>Adaptive Access Control:</strong> A method of access control that uses real-time risk assessments to dynamically adjust access privileges based on the user's behavior and other contextual factors. It can help to prevent unauthorized access to APIs by detecting and responding to suspicious activity in real-time.</p>
</li>
</ul>
<h1 id="heading-api-rate-limiting">API Rate Limiting</h1>
<p>API rate limiting is a technique used to prevent API abuse by limiting the number of requests that can be made over a period of time. This can help to ensure API availability and prevent system overload or performance issues caused by excessive API usage.</p>
<p>API rate limiting can be implemented in a number of ways, such as:</p>
<ol>
<li><p>Fixed Rate Limiting: This approach sets a fixed limit on the number of requests that can be made per unit of time, such as 100 requests per minute. Once the limit is reached, further requests are blocked or delayed until the next time period.</p>
</li>
<li><p>Dynamic Rate Limiting: This approach dynamically adjusts the rate limit based on real-time traffic patterns and usage patterns. For example, it may allow more requests during off-peak hours or for certain users or applications that have a higher priority.</p>
</li>
<li><p>Token Bucket Algorithm: This algorithm uses a token bucket to limit the rate of incoming requests. Tokens are added to the bucket at a fixed rate, and each request consumes a token. If the bucket is empty, further requests are blocked until more tokens are added.</p>
</li>
</ol>
<p>API rate limiting can be enforced at different levels, such as on a per-user basis, per-application basis, or across the entire API. It is important to carefully tune the rate limits to balance API availability with protection against abuse, and to provide informative error messages to API clients when rate limits are exceeded.</p>
<p>In summary, API rate limiting is an important tool for ensuring API availability and preventing abuse. It can be implemented in a variety of ways and at different levels, and should be carefully tuned to balance performance and security requirements.</p>
<h1 id="heading-api-encryption">API encryption</h1>
<p>Encryption typically involves two processes: encryption and decryption. Encryption is the process of converting plaintext data into a form that is unreadable without the appropriate key or password. Decryption is the process of converting the encrypted data back into plaintext.</p>
<p>There are several encryption techniques that can be used to secure APIs, including:</p>
<ul>
<li><p>SSL/TLS: Secure Sockets Layer (SSL) and its successor, Transport Layer Security (TLS), are encryption protocols that are commonly used to secure web traffic, including API requests and responses. SSL/TLS encrypts data in transit between the client and server using a combination of symmetric and asymmetric encryption.</p>
</li>
<li><p>AES: Advanced Encryption Standard (AES) is a symmetric encryption algorithm that is widely used to encrypt data at rest and in transit. AES can use different key sizes and modes of operation to provide varying levels of security.</p>
</li>
<li><p>Public Key Cryptography: Public key cryptography is an asymmetric encryption technique that uses a pair of keys, one public and one private, to encrypt and decrypt data. Public key cryptography is commonly used for secure key exchange and digital signatures.</p>
</li>
</ul>
<p>API encryption is an essential part of API security. It helps to protect sensitive information from being intercepted or tampered with during transmission, and ensures that only authorized parties can access the data.</p>
<h1 id="heading-api-versioning">API versioning</h1>
<p>API versioning is a crucial aspect of API design and development. It involves assigning a unique identifier or version number to each API, which allows developers to manage changes and ensure backward compatibility.</p>
<p>As APIs evolve and new features are added, it is essential to maintain compatibility with existing clients and avoid breaking changes that may result in service disruptions. By versioning APIs, developers can implement changes to the API without breaking the functionality of existing clients.</p>
<p>There are different approaches to versioning APIs, including:</p>
<ol>
<li><p>URL Versioning: In this approach, the version number is included in the API endpoint URL. For example, /api/v1/users.</p>
</li>
<li><p>Query Parameter Versioning: In this approach, the version number is included as a query parameter in the API endpoint URL. For example, /api/users?version=1.</p>
</li>
<li><p>Header Versioning: In this approach, the version number is included in a custom header in the API request. For example, X-API-Version: 1.</p>
</li>
</ol>
<p>It is important to choose a versioning approach that aligns with the requirements of the API and the needs of the developers using it. Additionally, it is important to document the API versioning strategy and communicate it to API consumers to ensure that they are aware of changes and can plan accordingly.</p>
<p>Properly managing API versions helps ensure that API consumers have a stable and reliable service and reduces the risk of breaking changes and service disruptions.</p>
<h1 id="heading-api-logging-and-monitoring">API Logging and Monitoring</h1>
<p>API logging and monitoring are essential for ensuring the security and reliability of APIs. Logging involves recording all requests and responses made to the API, along with any errors or exceptions that occur. This information can be used to identify and troubleshoot issues, as well as monitor usage patterns, and track performance metrics.</p>
<p>Monitoring involves actively tracking the API for anomalies, unusual behavior, and potential security threats. This can involve setting up automated alerts and notifications for specific events, such as failed login attempts or excessive API usage. By proactively monitoring APIs, developers can quickly identify and respond to potential issues before they escalate.</p>
<p>Some key considerations for API logging and monitoring include:</p>
<ul>
<li><p>Defining clear logging and monitoring requirements during API design and development</p>
</li>
<li><p>Selecting appropriate tools and systems for capturing and analyzing API logs and metrics</p>
</li>
<li><p>Regularly reviewing and analyzing logs to identify patterns and trends</p>
</li>
<li><p>Establishing alert thresholds and notification mechanisms to respond to potential security threats and service disruptions</p>
</li>
<li><p>Continuously improving logging and monitoring practices based on feedback and insights gained from analysis</p>
</li>
</ul>
<h1 id="heading-api-testing">API Testing</h1>
<p>API testing is essential for ensuring the security and reliability of APIs. There are different types of API tests, including functional tests, load tests, security tests, and integration tests. Each type of test focuses on a specific aspect of the API's functionality and performance.</p>
<p>Functional tests focus on ensuring that the API functions as intended, and that all features and capabilities are working correctly. Load tests focus on testing the API's ability to handle large volumes of traffic and requests, and to ensure that it can maintain performance under heavy loads.</p>
<p>Security tests focus on identifying potential security vulnerabilities and threats, such as SQL injection, cross-site scripting, and unauthorized access. Integration tests focus on testing the API's ability to integrate with other systems and services, such as third-party APIs and databases.</p>
<h1 id="heading-access-control-list-acl">Access Control List (ACL)</h1>
<p>Access Control Lists (ACLs) are a method of access control used to define and enforce permissions for resources on a server or network. ACLs are essentially a list of rules that specify which users or groups are allowed to access certain resources or perform specific actions. They can be used in combination with other authentication and authorization methods to provide fine-grained control over API access. ACLs require careful management and configuration to ensure that permissions are properly defined and enforced.</p>
<h3 id="heading-here-are-some-common-access-control-methods-used-in-api-security">Here are some common access control methods used in API security:</h3>
<ol>
<li><p><strong>Role-based Access Control (RBAC):</strong> is a widely used access control method that assigns permissions based on the role of the user or client. RBAC is often used in large organizations where there are many users with different levels of access to resources. With RBAC, access is granted based on predefined roles, which are then assigned to users or groups of users. For example, a user with an "admin" role might have access to more resources than a user with a "guest" role. RBAC is a simple and effective way to manage access control for large groups of users, and it can help to minimize the risk of unauthorized access or data breaches. However, RBAC can be inflexible and may not be well-suited to situations where more granular access control is required.</p>
</li>
<li><p><strong>Attribute-based Access Control (ABAC):</strong> is a method of access control that assigns permissions based on various attributes of the user or client. Attributes can include factors such as the user's location, job title, or department, as well as other criteria such as the time of day or the type of device being used to access the resource. ABAC allows for a more granular level of control over access permissions than other methods, such as role-based access control (RBAC), which assigns permissions based solely on the user's role. ABAC policies can be complex and difficult to manage, but they can be particularly useful in environments where access permissions need to be tightly controlled based on specific criteria.</p>
</li>
<li><p><strong>Mandatory Access Control (MAC):</strong> is an access control method used to enforce security policies on a system. In this method, access to resources is controlled by a set of rules that are predefined and enforced by the operating system or network. This means that users cannot modify or override the rules to gain access to resources that they should not have access to. The policies are typically defined by a security administrator, and they are enforced at the system level, rather than the application level. MAC is often used in environments where the security of the system is critical, such as government or military systems, or in situations where there is a need to protect sensitive data or resources. MAC can be more complex to implement and manage than other access control methods, but it provides a high level of security and control.</p>
</li>
<li><p><strong>Discretionary Access Control (DAC):</strong> is a type of access control method that allows the owner of a resource to determine who has access to it and what actions they can perform. In DAC, the owner of a resource has full control over who is granted access and what they can do once they have access. This can be useful in situations where the resource owner needs to maintain tight control over who can access the resource and how it is used. However, DAC can also be more prone to human error and abuse, as it relies on individuals to make access control decisions rather than a centralized system of rules and policies. DAC is often used in conjunction with other access control methods to provide additional layers of security and control.</p>
</li>
<li><p><strong>Context-based Access Control (CBAC):</strong> takes into account contextual information about the request before granting access. CBAC uses contextual factors such as location, time of day, the device being used, and user behavior to determine whether a request is legitimate or not. This method is useful for organizations that need to enforce stricter security policies in certain situations. For example, an organization might restrict access to certain resources from outside the office network or only allow access during specific times of the day. CBAC can be challenging to implement as it requires collecting and analyzing contextual data, but it can provide a high level of security when properly configured.</p>
</li>
</ol>
<h1 id="heading-the-principle-of-least-privilege-polp">The Principle of Least Privilege (PoLP)</h1>
<p>PoLP is a security concept that states that a user or process should only have access to the resources necessary to perform their job or function. This means that users should not have any unnecessary privileges or permissions that could potentially be exploited by attackers. The goal of the PoLP is to limit the potential damage that can be caused by a compromised account or process. By restricting access to resources, the PoLP helps to prevent attackers from moving laterally through a system and accessing additional sensitive data or resources. Implementing the PoLP can be challenging, as it requires careful analysis of user roles and permissions, as well as regular monitoring and maintenance to ensure that privileges are not being abused. However, it is an important principle to follow in order to maintain a secure API and prevent unauthorized access to sensitive data.</p>
<h1 id="heading-conclusion">Conclusion</h1>
<p>In conclusion, API security is a critical component of modern web application security. While the methods and best practices outlined in this blog, such as authentication and access control, are effective in securing APIs, it is important to note that there are many other strategies and techniques available. It is up to each organization to carefully evaluate their security needs and implement appropriate measures to protect their APIs and the data they contain. Regularly reviewing and updating API security policies and procedures is also crucial in ensuring that they remain effective and relevant in the face of evolving security threats.</p>
]]></content:encoded></item><item><title><![CDATA[ScriptKit: A Powerful Automation Tool for Developers]]></title><description><![CDATA[If you're a developer looking for a powerful automation tool that works across multiple platforms, ScriptKit is worth checking out. Developed by John Lindquist, ScriptKit is a cross-platform app that allows users to write and run scripts in JavaScrip...]]></description><link>https://blog.farismohamed.me/scriptkit-a-powerful-automation-tool-for-developers</link><guid isPermaLink="true">https://blog.farismohamed.me/scriptkit-a-powerful-automation-tool-for-developers</guid><category><![CDATA[automation]]></category><category><![CDATA[TypeScript]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[efficiency]]></category><category><![CDATA[Developer]]></category><dc:creator><![CDATA[Faris Mohamed]]></dc:creator><pubDate>Sun, 19 Mar 2023 07:44:18 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1679209835749/7b794190-48ee-40a3-b603-6e7f9db72acc.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you're a developer looking for a powerful automation tool that works across multiple platforms, <a target="_blank" href="https://www.scriptkit.com/">ScriptKit</a> is worth checking out. Developed by <a target="_blank" href="https://johnlindquist.com/">John Lindquist</a>, ScriptKit is a cross-platform app that allows users to write and run scripts in JavaScript or TypeScript, automate common development tasks, and integrate with a variety of popular developer tools and services.</p>
<blockquote>
<h2 id="heading-what-is-script-kit"><strong>What is Script Kit?</strong></h2>
<p>How often do you avoid scripting something because it takes too much effort?</p>
<p>Script Kit makes it easy to create and run scripts that solve your daily problems. Create a new script from the prompt then your script opens in the editor of your choice. Write a few lines of JavaScript. Then run the script from the prompt.</p>
<p>Simply put, Script Kit helps you script away the friction of your day. - from <a target="_blank" href="https://www.scriptkit.com/">scriptkit.com</a></p>
</blockquote>
<p>One of the main advantages of ScriptKit is its ease of use. With its intuitive interface, users can quickly create scripts to automate a wide range of tasks, from simple file management to complex workflows involving multiple steps and integrations.</p>
<p>Some of ScriptKit's key features include:</p>
<ol>
<li><p><strong>Ease of Use:</strong> ScriptKit supports JavaScript and TypeScript. so anyone familiar with basic javascript can start their automation journey with Scriptkit.</p>
</li>
<li><p><strong>Task Runner:</strong> ScriptKit includes a task runner that allows users to automate common development tasks, like running build commands or deploying code to a remote server. Users can define tasks using a simple syntax, and then run them with a single click.</p>
</li>
<li><p><strong>Integration with Popular Tools:</strong> ScriptKit integrates with a variety of popular developer tools and services, including GitHub, GitLab, and Slack. This allows users to create custom workflows that leverage these tools to streamline their development process.</p>
</li>
<li><p><strong>Sharing and Collaboration:</strong> ScriptKit allows users to share their scripts with others, either by exporting them as standalone scripts or by sharing them directly from within the app. This makes it easy for teams to collaborate on scripts and share automation workflows.</p>
</li>
<li><p>other key features are mentioned <a target="_blank" href="https://www.scriptkit.com/#:~:text=of%20your%20day.-,Key%20Features,-%E2%96%AA%EF%B8%8ELaunch%20the">here</a></p>
</li>
</ol>
<p>One of the best things about ScriptKit is that it's now available on Windows and Linux, in addition to macOS. This means that developers on all three major desktop platforms can take advantage of ScriptKit's powerful automation features and streamline their workflow. And because ScriptKit uses JavaScript and TypeScript, developers can easily port their existing scripts between platforms without having to learn a new language or toolset.</p>
<p>here's Matt Pocock's video on ScriptKit 👇🏼</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/C14MSrJGGBg">https://youtu.be/C14MSrJGGBg</a></div>
<p> </p>
<h3 id="heading-a-small-example-i-tried-out-to-learn-more-about-scriptkit">A small example I tried out to learn more about Scriptkit</h3>
<p>This script accepts a git URL, lets you select a folder where to clone that repo, and opens the cloned repo in vs code.</p>
<pre><code class="lang-javascript">
<span class="hljs-keyword">import</span> <span class="hljs-string">"@johnlindquist/kit"</span>;

<span class="hljs-keyword">const</span> git_url = <span class="hljs-keyword">await</span> arg(<span class="hljs-string">"enter git url"</span>);

cd(<span class="hljs-keyword">await</span> selectFolder());

<span class="hljs-keyword">await</span> $<span class="hljs-string">`git clone <span class="hljs-subst">${git_url}</span> -q`</span>;
<span class="hljs-keyword">await</span> $<span class="hljs-string">`code <span class="hljs-subst">${git_url.split(<span class="hljs-string">"/"</span>).at(<span class="hljs-number">-1</span>).split(<span class="hljs-string">"."</span>)[<span class="hljs-number">0</span>]}</span>`</span>;
</code></pre>
<p>Overall, ScriptKit is a powerful automation tool for developers on all major desktop platforms. With its powerful code editor, task runner, and integration with popular developer tools and services, ScriptKit is a must-have tool for developers looking to boost their productivity and save time.</p>
<p><strong>References</strong></p>
<ul>
<li><p><a target="_blank" href="https://www.scriptkit.com/">https://www.scriptkit.com/</a></p>
</li>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=C14MSrJGGBg&amp;ab_channel=MattPocock">https://www.youtube.com/watch?v=C14MSrJGGBg</a></p>
</li>
<li><p><a target="_blank" href="https://github.com/johnlindquist/kit/blob/main/API.md">https://github.com/johnlindquist/kit/blob/main/API.md</a></p>
</li>
<li><p><a target="_blank" href="https://www.scriptkit.com/blog">https://www.scriptkit.com/blog</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Deploy Your First Machine Learning Model Easily]]></title><description><![CDATA[🎉 🎉  tadaaa !!!
So this is my first personal blog post, I've been planning this for a looooong time And yes it's a start.
Disclaimer
In this post, I'm not adding any machine learning theories or concepts behind the model we're building as I'm on my...]]></description><link>https://blog.farismohamed.me/deploy-your-first-machine-learning-model</link><guid isPermaLink="true">https://blog.farismohamed.me/deploy-your-first-machine-learning-model</guid><category><![CDATA[TensorFlow]]></category><category><![CDATA[Machine Learning]]></category><category><![CDATA[Artificial Intelligence]]></category><category><![CDATA[Heroku]]></category><category><![CDATA[Flask Framework]]></category><dc:creator><![CDATA[Faris Mohamed]]></dc:creator><pubDate>Sun, 08 Aug 2021 16:30:57 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1628432332654/VC8T0DCH-.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>🎉 🎉  tadaaa !!!
So this is my first personal blog post, I've been planning this for a looooong time And yes it's a start.</p>
<h2 id="disclaimer">Disclaimer</h2>
<p>In this post, I'm not adding any machine learning theories or concepts behind the model we're building as I'm on my path to learning more about the Theory behind the Machine learning algorithms. This article is based on my researches for completing a challenge to participate in the  <a target="_blank" href="https://tinkerhub.org/bootcamp">AI Bootcamp</a>  by the  <a target="_blank" href="https://tinkerhub.org/">Tinkerhub Foundation</a>. I'm the kind of person who wants to see an initial output to get motivated to learn more. So whenever I start to learn something I'd build and deploy a real-world application initially and then start learning how things work behind the scene, and this is one of such adventures. </p>
<h2 id="prerequisites">Prerequisites</h2>
<p>Some experience in building softwares of any kind is recommended, although we're using python as the programming language, deep knowledge in python is not required as you can easily follow if you have any other programming experience.</p>
<h2 id="lets-get-started">Let's get started</h2>
<p>We're gonna use the  <a target="_blank" href="https://keras.io/">Keras</a> API to build and train the image classifier model using the  <a target="_blank" href="https://www.tensorflow.org/">tensorflow</a> library and the dataset used is the popular  <a target="_blank" href="https://www.cs.toronto.edu/~kriz/cifar.html">cifar-10</a> dataset. As I told you that I've almost zero experience with Machine Learning stuffs I've referred this  <a target="_blank" href="https://www.geeksforgeeks.org/cifar-10-image-classification-in-tensorflow/">article</a>  for building the model. </p>
<h3 id="training-the-model">Training the model</h3>
<p>The code below is used to train the model.</p>
<pre><code><span class="hljs-keyword">import</span> tensorflow <span class="hljs-keyword">as</span> tf  

<span class="hljs-comment"># Display the version</span>
print(tf.__version__)    

<span class="hljs-comment"># other imports</span>
<span class="hljs-keyword">import</span> numpy <span class="hljs-keyword">as</span> np
<span class="hljs-keyword">import</span> matplotlib.pyplot <span class="hljs-keyword">as</span> plt
<span class="hljs-keyword">from</span> tensorflow.keras.layers <span class="hljs-keyword">import</span> Input, Conv2D, Dense, Flatten, Dropout
<span class="hljs-keyword">from</span> tensorflow.keras.layers <span class="hljs-keyword">import</span> GlobalMaxPooling2D, MaxPooling2D
<span class="hljs-keyword">from</span> tensorflow.keras.layers <span class="hljs-keyword">import</span> BatchNormalization
<span class="hljs-keyword">from</span> tensorflow.keras.models <span class="hljs-keyword">import</span> Model
<span class="hljs-keyword">from</span> tensorflow.keras.models <span class="hljs-keyword">import</span> load_model


<span class="hljs-comment"># Load in the data</span>
cifar10 = tf.keras.datasets.cifar10

<span class="hljs-comment"># Distribute it to train and test set</span>
(x_train, y_train), (x_test, y_test) = cifar10.load_data()
print(x_train.shape, y_train.shape, x_test.shape, y_test.shape)


<span class="hljs-comment"># Reduce pixel values</span>
x_train, x_test = x_train / <span class="hljs-number">255.0</span>, x_test / <span class="hljs-number">255.0</span>

<span class="hljs-comment"># flatten the label values</span>
y_train, y_test = y_train.flatten(), y_test.flatten()


<span class="hljs-comment"># visualize data by plotting images</span>
fig, ax = plt.subplots(<span class="hljs-number">5</span>, <span class="hljs-number">5</span>)
k = <span class="hljs-number">0</span>

<span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(<span class="hljs-number">5</span>):
    <span class="hljs-keyword">for</span> j <span class="hljs-keyword">in</span> range(<span class="hljs-number">5</span>):
        ax[i][j].imshow(x_train[k], aspect=<span class="hljs-string">'auto'</span>)
        k += <span class="hljs-number">1</span>

plt.show()


<span class="hljs-comment"># number of classes</span>
K = len(set(y_train))

<span class="hljs-comment"># calculate total numer of classes</span>
<span class="hljs-comment"># for output layer</span>
print(<span class="hljs-string">"number of classes:"</span>, K)

<span class="hljs-comment"># Build the model using the functional API</span>
<span class="hljs-comment"># input layer</span>
i = Input(shape=x_train[<span class="hljs-number">0</span>].shape)
x = Conv2D(<span class="hljs-number">32</span>, (<span class="hljs-number">3</span>, <span class="hljs-number">3</span>), activation=<span class="hljs-string">'relu'</span>, padding=<span class="hljs-string">'same'</span>)(i)
x = BatchNormalization()(x)
x = Conv2D(<span class="hljs-number">32</span>, (<span class="hljs-number">3</span>, <span class="hljs-number">3</span>), activation=<span class="hljs-string">'relu'</span>, padding=<span class="hljs-string">'same'</span>)(x)
x = BatchNormalization()(x)
x = MaxPooling2D((<span class="hljs-number">2</span>, <span class="hljs-number">2</span>))(x)

x = Conv2D(<span class="hljs-number">64</span>, (<span class="hljs-number">3</span>, <span class="hljs-number">3</span>), activation=<span class="hljs-string">'relu'</span>, padding=<span class="hljs-string">'same'</span>)(x)
x = BatchNormalization()(x)
x = Conv2D(<span class="hljs-number">64</span>, (<span class="hljs-number">3</span>, <span class="hljs-number">3</span>), activation=<span class="hljs-string">'relu'</span>, padding=<span class="hljs-string">'same'</span>)(x)
x = BatchNormalization()(x)
x = MaxPooling2D((<span class="hljs-number">2</span>, <span class="hljs-number">2</span>))(x)

x = Conv2D(<span class="hljs-number">128</span>, (<span class="hljs-number">3</span>, <span class="hljs-number">3</span>), activation=<span class="hljs-string">'relu'</span>, padding=<span class="hljs-string">'same'</span>)(x)
x = BatchNormalization()(x)
x = Conv2D(<span class="hljs-number">128</span>, (<span class="hljs-number">3</span>, <span class="hljs-number">3</span>), activation=<span class="hljs-string">'relu'</span>, padding=<span class="hljs-string">'same'</span>)(x)
x = BatchNormalization()(x)
x = MaxPooling2D((<span class="hljs-number">2</span>, <span class="hljs-number">2</span>))(x)

x = Flatten()(x)
x = Dropout(<span class="hljs-number">0.2</span>)(x)

<span class="hljs-comment"># Hidden layer</span>
x = Dense(<span class="hljs-number">1024</span>, activation=<span class="hljs-string">'relu'</span>)(x)
x = Dropout(<span class="hljs-number">0.2</span>)(x)

<span class="hljs-comment"># last hidden layer i.e.. output layer</span>
x = Dense(K, activation=<span class="hljs-string">'softmax'</span>)(x)

model = Model(i, x)

<span class="hljs-comment"># model description</span>
model.summary()


<span class="hljs-comment"># Compile</span>
model.compile(optimizer=<span class="hljs-string">'adam'</span>,
              loss=<span class="hljs-string">'sparse_categorical_crossentropy'</span>,
              metrics=[<span class="hljs-string">'accuracy'</span>])

_epochs = <span class="hljs-number">10</span>

<span class="hljs-comment"># Fit</span>
r = model.fit(
  x_train, y_train, validation_data=(x_test, y_test), epochs=_epochs)


<span class="hljs-comment"># Fit with data augmentation</span>
<span class="hljs-comment"># Note: if you run this AFTER calling</span>
<span class="hljs-comment"># the previous model.fit()</span>
<span class="hljs-comment"># it will CONTINUE training where it left off</span>
batch_size = <span class="hljs-number">32</span>
data_generator = tf.keras.preprocessing.image.ImageDataGenerator(
  width_shift_range=<span class="hljs-number">0.1</span>, height_shift_range=<span class="hljs-number">0.1</span>, horizontal_flip=<span class="hljs-literal">True</span>)

train_generator = data_generator.flow(x_train, y_train, batch_size)
steps_per_epoch = x_train.shape[<span class="hljs-number">0</span>] // batch_size

r = model.fit(train_generator, validation_data=(x_test, y_test),
              steps_per_epoch=steps_per_epoch, epochs=_epochs)


<span class="hljs-comment"># Plot accuracy per iteration</span>
plt.plot(r.history[<span class="hljs-string">'accuracy'</span>], label=<span class="hljs-string">'acc'</span>, color=<span class="hljs-string">'red'</span>)
plt.plot(r.history[<span class="hljs-string">'val_accuracy'</span>], label=<span class="hljs-string">'val_acc'</span>, color=<span class="hljs-string">'green'</span>)
plt.legend()


<span class="hljs-comment"># label mapping</span>

labels = <span class="hljs-string">'''airplane automobile bird cat deer dog frog horse ship truck'''</span>.split()

<span class="hljs-comment"># select the image from our test dataset</span>
image_number = <span class="hljs-number">0</span>

<span class="hljs-comment"># display the image</span>
plt.imshow(x_test[image_number])

<span class="hljs-comment"># load the image in an array</span>
n = np.array(x_test[image_number])

<span class="hljs-comment"># reshape it</span>
p = n.reshape(<span class="hljs-number">1</span>, <span class="hljs-number">32</span>, <span class="hljs-number">32</span>, <span class="hljs-number">3</span>)

<span class="hljs-comment"># pass in the network for prediction and</span>
<span class="hljs-comment"># save the predicted label</span>
predicted_label = labels[model.predict(p).argmax()]

<span class="hljs-comment"># load the original label</span>
original_label = labels[y_test[image_number]]

<span class="hljs-comment"># display the result</span>
print(<span class="hljs-string">"Original label is {} and predicted label is {}"</span>.format(
    original_label, predicted_label))

  <span class="hljs-comment"># save the model</span>
model.save(<span class="hljs-string">'cifar-10.model.h5'</span>)
</code></pre><p>I would prefer using the  <a target="_blank" href="https://colab.research.google.com/">google colab</a> for the initial experiments, you can easily download the final model (.h5) file from the files section of the colab notebook. the model training may take almost 8 minutes for each iteration. I'm not going for a more detailed explanation of each line of code, you can find them in-depth from the keras/tensorflow documentaions.</p>
<h3 id="building-an-api-with-the-trained-model">Building An API with the trained model</h3>
<p>After executing the above code in the google colab notebook, You can download the model from the files section</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1628436249319/PSrNpeNfL.png" alt="Screenshot from 2021-08-08 20-53-50.png" />
For creating an API we're using the  <a target="_blank" href="https://flask.palletsprojects.com/en/2.0.x/">Flask framework</a>. 
First, create a new project folder </p>
<pre><code>mkdir ~/image-classifier-demo
<span class="hljs-built_in">cd</span> image-classifier-demo
</code></pre><p>   Then create a new python virtual environment</p>
<pre><code><span class="hljs-attribute">python3</span> -m venv demo-env
</code></pre><p>Now activate your virtual environment</p>
<pre><code><span class="hljs-keyword">source</span> demo-env/bin/activate
</code></pre><p><strong>Installing required packages</strong></p>
<pre><code>pip <span class="hljs-keyword">install</span> <span class="hljs-comment">--upgrade tensorflow-cpu flask flask-cors opencv-python-headless gunicorn</span>
</code></pre><p>after installing all the packages let's start coding. First, create a file called predict.py to add the image processing and prediction.</p>
<pre><code><span class="hljs-keyword">from</span> tensorflow.keras.preprocessing.image <span class="hljs-keyword">import</span> img_to_array
<span class="hljs-keyword">from</span> tensorflow.keras.models <span class="hljs-keyword">import</span> load_model
<span class="hljs-keyword">import</span> cv2
<span class="hljs-keyword">import</span> numpy <span class="hljs-keyword">as</span> np


names = <span class="hljs-string">'''airplane automobile bird cat deer dog frog horse ship truck'''</span>.split()
model = load_model(<span class="hljs-string">"models/cifar-10.model.h5.h5"</span>)

<span class="hljs-comment"># Process image and predict label</span>

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">processImg</span>(<span class="hljs-params">IMG_PATH</span>):</span>
    <span class="hljs-comment"># Preprocess image</span>
    image = cv2.imread(IMG_PATH)
    image = cv2.resize(image, (<span class="hljs-number">32</span>, <span class="hljs-number">32</span>))
    image = image.astype(<span class="hljs-string">"float"</span>) / <span class="hljs-number">255.0</span>
    image = img_to_array(image)
    image = np.expand_dims(image, axis=<span class="hljs-number">0</span>)

    res = model.predict(image)

    label = np.argmax(res)
    labelName = names[label]
    print(<span class="hljs-string">"The image is of "</span>, labelName)
    print(<span class="hljs-string">"confidence: "</span>, np.max(res))

    ret = dict()
    ret[<span class="hljs-string">'label'</span>] = labelName
    ret[<span class="hljs-string">'confidence'</span>] = str(np.max(res))
    <span class="hljs-keyword">return</span> ret
</code></pre><p>this function predicts the label and the confidence of the given image. to test it out add a test image to the folder and invoke the function with the relative path of the image as given below</p>
<pre><code><span class="hljs-selector-tag">processImg</span>(<span class="hljs-string">'./test-image.jpg'</span>)
</code></pre><p>So this is the major part of the API and now we only need to connect it with an API route. For that, we use the Flask web server. create an app.py file</p>
<pre><code><span class="hljs-keyword">from</span> flask <span class="hljs-keyword">import</span> Flask, render_template, request, jsonify
<span class="hljs-keyword">from</span> flask_cors <span class="hljs-keyword">import</span> CORS
<span class="hljs-keyword">from</span> predict <span class="hljs-keyword">import</span> processImg

<span class="hljs-comment"># Initializing flask application</span>
app = Flask(__name__)
cors = CORS(app)

<span class="hljs-meta">@app.route("/predict", methods=["POST"])</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">processReq</span>():</span>
    data = request.files[<span class="hljs-string">"img"</span>]
    data.save(<span class="hljs-string">"img.jpg"</span>)

    resp = processImg(<span class="hljs-string">"img.jpg"</span>)

    text = <span class="hljs-string">"it is a &lt;b&gt;"</span>+resp[<span class="hljs-string">'label'</span>] + \
        <span class="hljs-string">"&lt;/b&gt; with confidence &lt;b&gt;"</span>+resp[<span class="hljs-string">'confidence'</span>]+<span class="hljs-string">"&lt;/b&gt;"</span>

    <span class="hljs-keyword">return</span> text

<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">'__main__'</span>:
    app.run()
</code></pre><p>The above code creates a web server with a post route /predict. You can test the API by uploading an image to the POST API using any API testing tools like  <a target="_blank" href="https://www.postman.com/">postman</a>  or  <a target="_blank" href="https://insomnia.rest/">insomnia</a>. </p>
<h3 id="deploy-the-api">🚀 Deploy the API</h3>
<p>So we have built the API, now we'll deploy it to the internet with the help of  <a target="_blank" href="https://www.heroku.com/">heroku</a>, there are many other platforms to deploy, we are now choosing heroku for simplicity. </p>
<p>create a Procfile with the below command. a proc file is required for heroku to run our code.  <a target="_blank" href="https://devcenter.heroku.com/articles/python-gunicorn">learn more</a> </p>
<pre><code><span class="hljs-attribute">web</span>: gunicorn <span class="hljs-attribute">app</span>:app
</code></pre><p>Now compile all the packages we use to a requirements.txt file</p>
<pre><code>pip <span class="hljs-keyword">freeze</span> &gt; requirements.txt
</code></pre><p>now we are all set for deployment. create an account on  <a target="_blank" href="https://www.heroku.com/">https://www.heroku.com/</a>. then install heroku cli from here<br /><a target="_blank" href="https://devcenter.heroku.com/articles/heroku-cli">https://devcenter.heroku.com/articles/heroku-cli</a> </p>
<p>login to heroku from command line</p>
<pre><code>heroku <span class="hljs-keyword">login</span>
</code></pre><p>initialize git </p>
<pre><code>git init 
git <span class="hljs-keyword">add</span> .
git <span class="hljs-keyword">commit</span> -m "Initial Commit"
</code></pre><p>create a new heroku app</p>
<pre><code>heroku <span class="hljs-keyword">create</span> image-classifier-demo
</code></pre><p>push our code to the heroku git repo</p>
<pre><code>git <span class="hljs-keyword">push</span> heroku master
</code></pre><p>Hurraaaay we've deployed our very first Machine learning API to the internet. the remote URL for the API will the provided by the heroku cli upon successful deployment or you can visit the heroku dashboard for API URL.</p>
<p>I've updated the basic API with an HTML form and pushed it to a git repo for reference. The link to the repo is given below</p>
<p> <a target="_blank" href="https://github.com/faris-mohamed10/tinkerhub-image-clasifier">https://github.com/faris-mohamed10/tinkerhub-image-clasifier</a> </p>
<h3 id="conclusion">Conclusion</h3>
<p>Thank you for spending your valuable time reading my article. Since it is my first attempt at writing, there may be some mistakes in the article. Feel free to shoot your suggestions below. Happy coding and wish you all the best.</p>
<h3 id="references">References</h3>
<ul>
<li><p><a target="_blank" href="https://www.geeksforgeeks.org/cifar-10-image-classification-in-tensorflow/">https://www.geeksforgeeks.org/cifar-10-image-classification-in-tensorflow/</a></p>
</li>
<li><p><a target="_blank" href="https://linuxize.com/post/how-to-install-tensorflow-on-ubuntu-20-04/">https://linuxize.com/post/how-to-install-tensorflow-on-ubuntu-20-04/</a></p>
</li>
<li><p><a target="_blank" href="https://devcenter.heroku.com/articles/getting-started-with-python">https://devcenter.heroku.com/articles/getting-started-with-python</a> </p>
</li>
</ul>
]]></content:encoded></item></channel></rss>