Hi! I'm Jose Haro Peralta, or just Jose. I'm a consultant, author, and insturctor based in London. I'm the author of Microservice APIs (www.manning.com/books/microservice-apis), the founder of microapis.io, and the creator of some popular open source libraries like fencer (github.com/abunuwas/fencer). Check out my latest online course: 𝐁𝐮𝐢𝐥𝐝 𝐀𝐏𝐈𝐬 𝐰𝐢𝐭𝐡 𝐏𝐲𝐭𝐡𝐨𝐧: 𝐅𝐚𝐬𝐭𝐀𝐏𝐈 𝐄𝐝𝐢𝐭𝐢𝐨𝐧 👇 ✅ microapis.teachable.com/p/build-apis-with-fastapi For years I've worked with companies big and small all around the world to help them build microservices, deliver API integrations, automate their infrastructure, write better code, and adopt best practices. My goal in this channel is to share with you everything I've learned over the past years about writing software and architecting systems. I also write regularly in my newsletter 👇 ✅ microapis.substack.com/ If you find my content interesting, don't forget to subscribe to my channel!
so can I implement this IAM Identity Center to limit the number of servers and databases the user can access using permission sets right? my company wants to properly implement strict measures on who and when some devs/data engineers can access some resources.
Thanks for your question! Permission sets are collections of IAM policies. With IAM policies, you can be absolutely granular on how users can access resources. So you can create a policy that gives read-only access to a specific S3 bucket, or a certain path within that bucket. Another policy with specific permissions to an EC2 instance or an RDS database, and so on. Then you can bring those policies together under a permission set. Is that the kind of access control you're looking for?
this explain is a joke? do you mean a program that are PROGRAMED DÃ to answer without a response of the home server from the "page". yes economy data sharing = only download, no upload. _l_ that would not be fake avertising from server providers?
Not sure if you’re commenting on the right video but to clarify this is a video about middleware, specifically about web middleware. Middleware is a layer of software that sits between the receiving end of your server and your controllers and allows you to apply various processing steps on each request
Thank you was a great pleasure meeting you too and I really enjoyed our conversation! Wish you the very best with your projects too and looking forward to seeing them grow. Hope we can see each other again!
Thank you for the help… Chatgpt could not do it actually what you have done. Just a request, you can now update the code as per latest development in FastAPI and update the okta token validation process as well. I have a question, can we use api routes, instead of the objectId when customizing openapi
Thank you for your comment and your suggestions 🚀🚀! I'm currently working on new tutorials about auth/authz with the latest version of FastAPI and I'll show how to do this with dependency injection, integrations with auth0, okta, and more! How are you planning to customise openapi with the API routes?
Thank you for your question! You'd follow the same approach shown in the video, only applying the filters first. Here's an example: @router.get("/jobs", response_model=ListJobs) def list_jobs(contract_type: ContractTypeEnum | None = None,): with session_maker() as session: query = select(Job) if contract_type: query = query.where(Job.contract_type == contract_type.value) count = session.execute( select(func.count()).select_from(query.subquery()) ).scalar_one() This endpoint returns a list of jobs and allows you to filter by contract type. The filter is optional and None by default, so first we check if it's set, and if so, we apply the filter to the query. Once we've filtered the result set, we count the items. Hope this helps, if you have any more questions please let me know!
Excellent work sir, thank you for your work. Do you know of anyway to avoid using the CDN for the OPEAPI_SWAGGER_UI_URL and other external urls? Assuming policy does not allow use of CDNs.
Thank you for your question! A workaround would be serving the Swagger UI assets from your own domain. For example, you can download the assets here: cdn.jsdelivr.net/npm/swagger-ui-dist/. You could serve them from Flask, from an S3 bucket if you use AWS, from Cloudflare if you use that, or any other alternative.
Ok, this looks good for CRUD. What about beyond CRUD? How do we do joins with this repo pattern? Or a simple subquery? How can we group queries into one instead of hitting the DB several times? I mean at least you're still tightly coupled to SQLAlchemy and you're returning the sqlalchemy instances as is. I've seen some repo patterns where people serialized those into intermediate objects, creating even bigger problems down the line cause of the need to re-fetch that sqlalchemy object in different functions. I feel like everyone goes for repository patterns for simple projects which ends up creating way more problems than it solves. Also, I love the repository registry idea, but am not loving the fact that it's injected into the request object. I think it would we way cleaner as a dependency!😁
Thanks for your comment @RamiAwar! This is a great discussion. First of all 💯 repository isn't suitable in all situations - if it doesn't help it has no place in our codebase. Re joins and subqueries - I think this is query repository shines. You are simply encapsulating the complexity of those queries away from your business and other layers. The example in the video may give the wrong impression that repository is a 1-to-1 between classes and tables, but that's not how it works in practice. Domain models usually pull data from multiple tables and the repository should serve those needs. Ideally, repository doesn't return SQLAlchemy objects, but DTOs or something similar like you say. In the tutorial, the repo's add() method returns an instance of a plain Booking object (github.com/abunuwas/repository-pattern-tutorial/blob/master/data_access/repository.py#L24) and the list() method returns a list of dictionaries (github.com/abunuwas/repository-pattern-tutorial/blob/master/data_access/repository.py#L14). A plain and simple DTO would be a better choice. Personally, I only use the repository pattern when I want to enforce a clear separation between data access and other layers for testing and other purposes, and when queries are growing complex and I want to abstract them away from the business layer. Hope these comments help and thanks again for sharing your thoughts!
Thank you @mlsandreas! If I'm going to build just an API, FastAPI is my choice. If I'm going to render HTML and such, I go with Flask. You can render HTML with FastAPI via Starlette too, but I just find Flask more convenient. Also I like the concept of middleware in Flask (aka plugins) slightly more. However, for the most part I find both frameworks very similar. Do you have a preference?x
That makes perfect sense! Only recommendation I make to organisations making this move is to use to use a proper Flask framework (aka plugin) for the API implementation 🚀
Very useful. Thanks for the guide! Its essential to get off on the right path with these complex setups. There is so much to stitch together these days that these tutorials are invaluable. Good job.
@microapis I've been using alembic a while now, and it's great. But I think they should have numbered the migration files so it sorts in the file system. It might be an easy thing to add. Might do a PR with that function added
Hi thank you for your question and sorry for my late reply! Bear in mind what we're injecting is the session factory, not the session itself. Do you have an example of the code you're struggling with?
When I try to use the context manager protocol, I get 'TypeError: 'AsyncSession' object does not support the context manager protocol' error, on the other hand, session = request.app.session_maker(), works as expected and I get result, but Postgres is complaining about pools. "Please ensure that SQLAlchemy pooled connections are returned to the pool explicitly, either by calling ``close()`` or by using appropriate context managers to manage their lifecycle." and await session.close(), does not seem to solve the problem.
Thank you for your question! Technically, Data Access Objects (DAOs) are objects that handle the implementation details of saving or retrieving data from a persistence storage. For example, if you use a SQL database, a DAO would take care of translating code to SQL statements. It's kind of related to Data Mapper, tho the idea in Data Mapper is to map data from the persistence storage into domain objects. So a Data Mapper may use a DAO to handle the low-level interactions with the db. Repository represents a collection of domain objects. It encapsulates the logic required to map db records to domain objects. In most situations, you don't have to handle DAOs directly. You'll normally use a SQLAlchemy model to write db queries using Python code. The SQLAlchemy model is your data mapper, and it'll use internal logic akin to a data access object to translate the code into SQL statements. I always recommend not introducing any business logic within SQLAlchemy models, and to keep them strictly as a data representation layer. So the way I use SQLAlchemy models is closer to a DAO. If you need to write very complex queries not worth doing with SQLAlchemy, then you'd write your own DAO. It could be a function that puts together the right SQL statement to retrieve some data. When you map that data to a domain object, you're writing a data mapper. All that logic would be encapsulated behind a repository. Note that I say a DAO could be a function despite its name saying data access OBJECT. Historically, the concept comes from the Java community, where everything used to be objects, si that was the only possible implementation. In Python, it can be anything you want and suits your needs. Hope this helps 🚀🚀!
Thank you for your question! In a real-world app we'd use a database, so this was just a choice to keep it super simple. You could just as well index by ID in a dictionary, it'd make access a lot faster 🚀!
Hey Jose, you have no idea how amazing this content is? I encourage everyone who sees this video to get a hotter and a cup of coffee. And Yes, I'd be interested in the coding examples, thank you.
✅ Like and subscribe for more videos like this! ✅ Check out my upcoming course 𝐁𝐮𝐢𝐥𝐝 𝐀𝐏𝐈𝐬 𝐰𝐢𝐭𝐡 𝐏𝐲𝐭𝐡𝐨𝐧: 𝐅𝐚𝐬𝐭𝐀𝐏𝐈 𝐄𝐝𝐢𝐭𝐢𝐨𝐧: microapis.teachable.com/p/build-apis-with-fastapi. Use the code 𝐩𝐫𝐞-𝐥𝐚𝐮𝐧𝐜𝐡 to get a 𝟐𝟓% 𝐝𝐢𝐬𝐜𝐨𝐮𝐧𝐭 during the pre-launch period.
Hi Dr Kingston thanks for the suggestion, that's an awesome idea! It's really not very difficult and these are great performance boosters. I used views extensively in a recent project to speed up queries for a machine learning engine. I'll put this on the list of upcoming videos 🚀!
Thank you for your kind words Shaheer! I'll release the following parts next year between January and February. I should've done that already, but work and family got in the way and didn't manage to find the time yet. Apologies for my delay!!