You are browsing as a guest. Sign up (or log in) to start making projects!

Nautica API

  • 9 Devlogs
  • 25 Total hours

Nautica is the backend platform that manages the runtime, lifecycle, routing and 3rd party plugins automatically.

Ship #1 Changes requested

## I’ve updated the Service Manager, including the dependency resolver. These changes include:
1. New lifecycle hook "onSetup", intended for setting up databases, etc.
I've mostly added this to split "start servers" and "setup things" all being in onStart. This way the separation between those 2 tasks is clear and helps to eliminate certain race conditions.

2. Toggle switches are now generated automatically
Before you had to manually declare a key in a config in onInstall, and then read it in isEnabled, which was just extra boilerplate. So I automated the process in the Service class.

3. "?", ":after" and ":after?" parameters for dependencies
Before this, the boot order was still fragile even with dependencies defined, because the ability to define a dependency, and make it start only AFTER your dependency is initialized wasn't a thing. Now you can do this by simply appending ":after" to the dependency name. "?" at the end also makes the dependency optional.

4. Few fixes relating to dependency resolution and boot orders

## HTTP API Got a decently big update as well..
1. The performance is now up ~70% from previous versions, finally surpassing FastAPI,
I've achieved this adding an option to disable unnecessary messages from being logged. Which only goes to show how heavy the logging manager I use is, but I doubt I'll be rewriting it, since the way it is now helps with DX.
2. Response validation using "@HTTP.Responses(...)" and ReplyModels:
Before you were able to only validate what's coming in, but not what's going out. The validator has a strict mode, which when enabled adds an extra layer of "security". If strict mode is disabled, the responses are only used for OpenAPI docs generation. Tho the framework may still complain if you're sending invalid responses.
3. Nested object validation and Require.ListOf
4. Static methods in Reply
Since the framework is built on Starlette, you may need to use Starlette's responses in some cases.
5. OpenAPI Docs generation
This was kinda a big thing on my list ever since I realized that I can automatically generate SDKs instead of having to write request calls manually. I also wanted to add a way to expose the docs with an endpoint, but I'm holding off on that.

***

The Package registry & manager were introduced as well. The package registry it itself built on Nautica, and works with the package manager integrated into the Nautica's CLI.
Likewise I've started work on the Landing page & docs website for the framework, but I'm putting it off for a bit, because of finals.

I've also fixed countless bugs, refactored things, and over all made many QoL changes, which helped to make the framework feel more polished.

***

This might be a strange project, since I'm somewhat "reinventing the wheel", but I really didn't like the way FastAPI, Flask and other Python HTTP frameworks work. It basically handles ONLY the http part, which is fine, but in bigger projects YOU have to manage everything else around it. When I was building small apps it wasn't that big of an issue, but it became pretty apparent in bigger projects. The complexity and boilerplate that comes with large projects isn't something I can handle well, while also having to enforce my own conventions.

I made Nautica to fix these issues, and I'd say I succeeded. The boilerplate that's needed per route is minimal, compared to other frameworks; The package manager adds an intuitive way to add plugins (services, packages), and the service system itself does a lot of the heavy lifting for you, by automatically deciding on the boot order instead of you having to write do it explicitly using imports, etc.

In conclusion, Nautica takes away some freedom and in exchange gives you structure, less boilerplate and tools to debug your code, which makes shipping apps easier and faster.

  • 9 devlogs
  • 25h
Try project → See source code →
Open comments for this post

3h 29m 29s logged

I’ve released v3.2.2, the new things there include:

  • OpenAPI Docs generator
  • Changed expression for nested requirements from nested(...) to {...}
  • Request schemas in errors can be hidden now
  • Added descriptions for commands in help
  • Renamed Reply.IsList() into .asList()
  • Added import aliases for Requirements in napi

These are mostly QoL changes, I made formatting of certain things so it’d be easier to read, use, or to make sense linguistically. I also made it a little bit more secure by giving other developers an option to hide their request schemas in error messages. I’ve also included the new benchmark numbers in the README.


OpenAPI Docs generator mostly works now, but it doesn’t expose the docs to /nautica:docs yet, I’m also considering making the endpoint the developer’s concern, and not the framework’s. Surprisingly it wasn’t as hard as i expected it to be, but some weird edge cases were definitely annoying to deal with.


Anyways, alongside the updates to the framework itself, I’ve also now documented the new changes made since version 3.0.2, so they’re now up to date with the latest release (that being 3.2.2). I know it took a while but i was more focused on releasing fixes and updates first.

https://github.com/xellu/nautica-api/wiki

https://github.com/xellu/nautica-api/compare/3.2.0...3.2.2

0
0
3
Open comments for this post

2h 31m 19s logged

I’ve started work on OpenAPI Docs generator, I’d imagine it’ll take me a while to complete. Anyways I’ve released v3.2, see below for new changes

Changelog

  1. Improved speed and latency
  2. New onSetup hook for services
  3. Auto Switch registration for services
  4. New Require.ListOf validator
  5. Validator support for nested objects
  6. Better dependency resolver

More on these changes here: post 1, post 2

And new, undocumented changes include:
7. Moving typeToString into models, from http api (didn’t really make sense to have it there)
8. Added static methods into Reply for starlette responses, these include:

Reply.plainText, Reply.html, Reply.stream, Reply.file, Reply.redirect.

Known Issues

v3.2.0’s dependency resolver incorrectly handles the :after parameter, a fix is already available in the branch for version 3.2.1

0
0
2
Open comments for this post

3h 30m 11s logged

I’ve added a few QoL features, those being:

Reply Models

Before, you could only verify whats coming IN, but not whats coming OUT of the server. Now, you can do that easily:

from napi.http import HTTP, Reply, Require, ReplyModel, Error

@HTTP.GET()
@HTTP.Responses(
    ReplyModel(200, str),
    ReplyModel(400, Error),
    strict= True
)
@HTTP.Require()
async def hello(ctx):
    if ctx.body.get("hello"): raise Error(400, "No hello")
    
    return "Hello World!"

In this case, the request will go through without an issue, but if, for example, you returned anything other than a string:

return 0

The request will fail automatically. This will also be useful for when I add OpenAPI generation, as the generator will have access to the responses.

This behavior can be disabled, by setting strict to False.

Nested object validation

@HTTP.Require(body = {"hello": {"world": str}) <- This code used to be invalid before.

I since added support for nested objects (no depth limit).

Automatic Toggle Switch Registration

Plugins used to register their own keys in the config, and then setup isEnabled method that would determine if the service should be started or not.

To reduce the headache and boilerplate of this approach, Nautica now automatically creates a key with your service’s name under services in config.n3. If you want your own logic in isEnabled, you can do so by overwriting the method. By doing so you’ll disable the automatic registration and the framework gives you the freedom to do it your way. If you want custom logic AND automatic registration, it can simply be combined by using super().isEnabled().

Require.ListOf(…)

I’d say this is a highly useful addition. It does exactly what it sounds like: It checks if all the items in a list match a certain schema.

Require.ListOf(str)

List of just strings

Require.ListOf({"hello": str})

List of dictionaries

Requrie.ListOf(Require.AnyTypeOf(str, int))

List of strings and integers

0
0
1
Open comments for this post

2h 33m 25s logged

I’ve been optimizing the framework today, here’s what changed:

1. Massive performance boosts

I managed to go from 2279 requests/sec to 3929, which is 72% increase. After running new benchmarks, I’ve also surpassed FastAPI by ~24% (recorded 3154 requests/sec). I did this by minimizing the amount of logging that is done per request (can be configured). Because my log manager is fairly heavy, this helped a lot.

2. Better dependency resolver

The dependency resolver I had for services was okay, but it lacked 2 important features: Optional dependencies and explicit order.

The old system was simply:

Service.Export(MyPlugin, depends_on=["HTTPRouter"])
Which is fine for simple plugins, but you start doing more complex work, you’ll hit the limits fast.

The new system now handles:

  • ? at the end makes the dependency optional
  • :after tells the dependency to start AFTER your plugin, not before. Essentially adds your plugin as the target’s dependency.

3. Split onStart

Before, onStart handled both starting database and HTTP servers, bots. Because of this, I’ve decided to split the setup logic and startup logic into 2: onSetup and onStart

4. Other changes

I also removed some legacy aliases for methods.

0
0
2
Open comments for this post

4h 36m 59s logged

Spent almost 5 hours on a navbar, finally figured it out though.

The open/close logic on hovering was a nightmare to do. In the end i settled for IDs and an event listener for mouseover. It’s probably one of the worse solutions, but I’m not gonna touch it since it works finally.

I also changed the background to something that fits better.

0
0
2
Open comments for this post

3h 52m 58s logged

I’ve started work on a web for the framework.

For now I only managed to set up the project and make the hero on the landing page, for which I took inspiration from payloadcms and rig.ai

The landing page itself was hard to make, since I had to figure out how to structure the grid, and even now it’s not up to my standards.

0
0
1
Open comments for this post

2h 14m 39s logged

Nautica Package Registry is Live!

napi install mongodb now downloads the package into project plugins and installs any PyPI dependencies automatically.

2 Packages are up already:

  • MongoDB: Adapter for pymongo
  • NAuth: A simple session manager (using Mongo)

The registry itself runs on Nautica, with both packages installed

https://github.com/xellu/nautica-package-manager
https://napm.xellu.xyz/

0
0
3
Open comments for this post

2h 17m 58s logged

Hello y’all. I’m making a framework for backend development, called Nautica. I’m also bundling a package manager, similar to npm/PyPI, to allow people to share their plugins.

I’ve started working on this project before Stardance, but this sounds like a good opportunity to get feedback on it.

Today’s update notes (v3.1.3):

  • Fixed shell sleeping while in systemd mode
  • Fixed file reading during http requests
  • Fixed package manager connection issues
  • Added commands to list http and websocket endpoints

For anyone interested in the specifics, the HTTP part of the API is built on top Starlette. Unlike FastAPI, I made my own request validation system that gives you more freedom, though it may perform worse under load.
From the benchmarks I’ve ran, my framework seems to be just a little faster than FastAPI (which is also based on Starlette):

  • FastAPI: 2259 requests/second
  • Nautica: 2271 requests/second ~0.53% faster
    Though these numbers are a bit dated, and may be off.

I’m still working on the package manager, but I’ll post a showcase of that soon. For now, here’s a showcase of how Nautica itself works:

0
0
2

Delete project?

Are you sure you want to permanently delete this project? This action cannot be undone.

All devlogs, followers, and associated data will be removed.

Followers

Loading…