Skip to content

Commit

Permalink
More docs, contributing, security
Browse files Browse the repository at this point in the history
  • Loading branch information
nhairs committed Nov 22, 2024
1 parent 0895a76 commit 0c41d3f
Show file tree
Hide file tree
Showing 10 changed files with 182 additions and 30 deletions.
1 change: 1 addition & 0 deletions CODE_OF_CONDUCT.md
42 changes: 40 additions & 2 deletions docs/changelog.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,44 @@
# Change Log
All notable changes to this project will be documented in this file.

## 2.0.0
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).


## [3.0.0](https://github.com/nhairs/nserver/compare/v2.0.0...dev) - UNRELEASED

!!! tip
Version `3.0.0` represents a large incompatible refactor of `nserver` with version `2.0.0` considered a ["misfire"](https://github.com/nhairs/nserver/pull/4#issuecomment-2254354192). If you have been using functionality from `2.0.0` or the development branch you should expect a large number of breaking changes.

### Added
- Add Python 3.13 support
- Generalised CLI interface for running applications; see `nserver --help`.
- Implemented in `nserver.cli`.
- `nserver.application` classes that focus on running a given server instance.
- This lays the ground work for different ways of running servers in the future; e.g. using threads.
- `nserver.server.RawNameServer` that handles `RawMiddleware` including exception handling.

### Removed
- Drop Python 3.7 support
- `nserver.server.SubServer` has been removed.
- `NameServer` instances can now be registered to other `NameServer` instances.

### Changed
- Refactored `nserver.server.NameServer`
- "Raw" functionality has been removed. This has been moved to the `nserver.server.RawNameServer`.
- "Transport" and other related "Application" functionality has been removed from `NameServer` instances. This has moved to the `nserver.application` classes.
- `NameServer` instances can now be registered to other instances. This replaces `SubServer` functionality that was in development.
- Refactoring of `nserver.server` and `nserver.middleware` classes.
- `NameServer` `name` argument / attribute is no longer used when creating the logger.

### Development Changes
- Development tooling has moved to `uv`.
- The tooling remains wrapped in `dev.sh`.
- This remove the requirement for `docker` in local development.
- Test suite added to GitHub Actions.
- Added contributing guidelies.

## [2.0.0](https://github.com/nhairs/nserver/compare/v1.0.0...v2.0.0) - 2023-12-20

- Implement [Middleware][middleware]
- This includes adding error handling middleware that facilitates [error handling][error-handling].
Expand All @@ -10,6 +48,6 @@
- Add [Blueprints][blueprints]
- Include refactoring `NameServer` into a new shared based `Scaffold` class.

## 1.0.0
## [1.0.0](https://github.com/nhairs/nserver/commit/628db055848c6543641d514b4186f8d953b6af7d) - 2023-11-03

- Beta release
107 changes: 107 additions & 0 deletions docs/contributing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# Contributing

Contributions are welcome!

## Code of Conduct

In general we follow the [Python Software Foundation Code of Conduct](https://policies.python.org/python.org/code-of-conduct/). Please note that we are not affiliated with the PSF.

## Pull Request Process

**0. Before you begin**

If you're not familiar with contributing to open source software, [start by reading this guide](https://opensource.guide/how-to-contribute/).

Be aware that anything you contribute will be licenced under [the project's licence](https://github.com/nhairs/nserver/blob/main/LICENSE). If you are making a change as a part of your job, be aware that your employer might own your work and you'll need their permission in order to licence the code.

### 1. Find something to work on

Where possible it's best to stick to established issues where discussion has already taken place. Contributions that haven't come from a discussed issue are less likely to be accepted.

The following are things that can be worked on without an existing issue:

- Updating documentation. This includes fixing in-code documentation / comments, and the overall docs.
- Small changes that don't change functionality such as refactoring or adding / updating tests.

### 2. Fork the repository and make your changes

We don't have styling documentation, so where possible try to match existing code. This includes the use of "headings" and "dividers" (this will make sense when you look at the code).

Common devleopment tooling has been wrapped in `dev.sh` (which uses `uv` under the hood).

Before creating your pull request you'll want to format your code and run the linters and tests:

```shell
# Format
./dev.sh format

# Lint
./dev.sh lint

# Tests
./dev.sh test
```

If making changes to the documentation you can preview the changes locally using `./dev.sh docs`. Changes to the README can be previewed using [`grip`](https://github.com/joeyespo/grip) (not included in `dev` dependencies).

!!! note
In general we will always squash merge pull requests so you do not need to worry about a "clean" commit history.

### 3. Checklist

Before pushing and creating your pull request, you should make sure you've done the following:

- Updated any relevant tests.
- Formatted your code and run the linters and tests.
- Updated the version number in `pyproject.toml`. In general using a `.devN` suffix is acceptable.
This is not required for changes that do no affect the code such as documentation.
- Add details of the changes to the change log (`docs/changelog.md`), creating a new section if needed.
- Add notes for new / changed features in the relevant docstring.

**4. Create your pull request**

When creating your pull request be aware that the title and description will be used for the final commit so pay attention to them.

Your pull request description should include the following:

- Why the pull request is being made
- Summary of changes
- How the pull request was tested - especially if not covered by unit testing.

Once you've submitted your pull request make sure that all CI jobs are passing. Pull requests with failing jobs will not be reviewed.

### 5. Code review

Your code will be reviewed by a maintainer.

If you're not familiar with code review start by reading [this guide](https://google.github.io/eng-practices/review/).

!!! tip "Remember you are not your work"

You might be asked to explain or justify your choices. This is not a criticism of your value as a person!

Often this is because there are multiple ways to solve the same problem and the reviewer would like to understand more about the way you solved.

## Common Topics

### Versioning and breaking compatability

This project uses semantic versioning.

In general backwards compatability is always preferred.

Feature changes MUST be compatible with all [security supported versions of Python](https://endoflife.date/python) and SHOULD be compatible with all unsupported versions of Python where [recent downloads over the last 90 days exceeds 10% of all downloads](https://pypistats.org/packages/nserver).

In general, only the latest `major.minor` version of NServer is supported. Bug fixes and feature backports requiring a version branch may be considered but must be discussed with the maintainers first.

See also [Security Policy](security.md).

### Spelling

The original implementation of this project used Australian spelling so it will continue to use Australian spelling for all code.

Documentation is more flexible and may use a variety of English spellings.

### Contacting the Maintainers

In general it is preferred to keep communication to GitHub, e.g. through comments on issues and pull requests. If you do need to contact the maintainers privately, please do so using the email addresses in the maintainers section of the `pyproject.toml`.
4 changes: 2 additions & 2 deletions docs/error-handling.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Error Handling

Custom exception handling is handled through the [`ExceptionHandlerMiddleware`][nserver.middleware.ExceptionHandlerMiddleware] and [`RawExceptionHandlerMiddleware`][nserver.middleware.RawExceptionHandlerMiddleware] [Middleware][middleware]. These middleware will catch any `Exception`s raised by their respective middleware stacks.
Custom exception handling is handled through the [`QueryExceptionHandlerMiddleware`][nserver.middleware.QueryExceptionHandlerMiddleware] and [`RawExceptionHandlerMiddleware`][nserver.middleware.RawExceptionHandlerMiddleware] [Middleware][middleware]. These middleware will catch any `Exception`s raised by their respective middleware stacks.

In general you are probably able to use the `ExceptionHandlerMiddleware` as the `RawExceptionHandlerMiddleware` is only needed to catch exceptions resulting from `RawMiddleware` or broken exception handlers in the `ExceptionHandlerMiddleware`. If you only write `QueryMiddleware` and your `ExceptionHandlerMiddleware` handlers never raise exceptions then you'll be good to go with just the `ExceptionHandlerMiddleware`.
In general you are probably able to use the `QueryExceptionHandlerMiddleware` as the `RawExceptionHandlerMiddleware` is only needed to catch exceptions resulting from `RawMiddleware` or broken exception handlers in the `QueryExceptionHandlerMiddleware`. If you only write `QueryMiddleware` and your `QueryExceptionHandlerMiddleware` handlers never raise exceptions then you'll be good to go with just the `QueryExceptionHandlerMiddleware`.

Both of these middleware have a default exception handler that will be used for anything not matching a registered handler. The default handler can be overwritten by registering a handler for the `Exception` class.

Expand Down
6 changes: 0 additions & 6 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@ NServer has been built upon [dnslib](https://github.com/paulc/dnslib) however us

NServer has been inspired by easy to use high level frameworks such as [Flask](https://github.com/pallets/flask) or [Requests](https://github.com/psf/requests).

!!! warning
NServer is currently Beta software and does not have complete documentation, testing, or implementation of certain features.


## Features

Expand Down Expand Up @@ -54,9 +51,6 @@ In the case of bug reports, please help us help you by following best practices

In the case of feature requests, please provide background to the problem you are trying to solve so to help find a solution that makes the most sense for the library as well as your usecase. Before making a feature request consider looking at my (roughly written) [design notes](https://github.com/nhairs/nserver/blob/main/DESIGN_NOTES.md).

## Contributing
I am still working through open source licencing and contributing, so not taking PRs at this point in time. Instead raise and issue and I'll try get to it as soon a feasible.

## Licence
This project is licenced under the MIT Licence - see [`LICENCE`](https://github.com/nhairs/nserver/blob/main/LICENCE).

Expand Down
9 changes: 3 additions & 6 deletions docs/middleware.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@

Middleware can be used to modify the behaviour of a server seperate to the individual rules that are registered to the server. Middleware is run on all requests and can modify both the input and response of a request.

!!! note
Middleware requires `nserver>=3.0`

## Middleware Stacks

Middleware operates in a stack with each middleware calling the middleware below it until one returns and the result is propagated back up the chain. NServer uses two stacks, the outmost stack deals with raw DNS records (`RawMiddleware`), which will eventually convert the record to a `Query` which will then be passed to the main `QueryMiddleware` stack.
Expand All @@ -19,7 +16,7 @@ For most use cases you likely want to use [`QueryMiddleware`][nserver.middleware

### Registering `QueryMiddleware`

`QueryMiddleware` can be registered to `NameServer` and `SubServer` instances using their `register_middleware` methods.
`QueryMiddleware` can be registered to `NameServer` instances using their `register_middleware` methods.

```python
from nserver import NameServer
Expand All @@ -41,7 +38,7 @@ from nserver import Query, Response
class MyLoggingMiddleware(QueryMiddleware):
def __init__(self, logging_name: str):
super().__init__()
self.logger = logging.getLogger(f"my-awesome-app.{name}")
self.logger = logging.getLogger(f"my-awesome-app.{logging_name}")
return

def process_query(
Expand All @@ -60,7 +57,7 @@ server.register_middleware(MyLoggingMiddleware("bar"))

Once processed the `QueryMiddleware` stack will look as follows:

- [`ExceptionHandlerMiddleware`][nserver.middleware.ExceptionHandlerMiddleware]
- [`QueryExceptionHandlerMiddleware`][nserver.middleware.QueryExceptionHandlerMiddleware]
- Customisable error handler for `Exception`s originating from within the stack.
- `<registered middleware>`
- [`HookMiddleware`][nserver.middleware.HookMiddleware]
Expand Down
14 changes: 14 additions & 0 deletions docs/security.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Security Policy

## Supported Versions

Security support for Python JSON Logger is provided for all [security supported versions of Python](https://endoflife.date/python) and for unsupported versions of Python where [recent downloads over the last 90 days exceeds 10% of all downloads](https://pypistats.org/packages/nserver).


As of 2024-11-22 security support is provided for Python versions `3.8+`.


## Reporting a Vulnerability

Please report vulnerabilties [using GitHub](https://github.com/nhairs/nserver/security/advisories/new).

9 changes: 1 addition & 8 deletions docs/subserver-blueprint.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# Sub-Servers and Blueprints


## Sub-Servers

To allow for composing an application into different parts, a [`NameServer`][nserver.server.NameServer] can be included in another `NameServer`.
Expand All @@ -11,9 +10,6 @@ Use cases:
- Reuse a server registered under different rules.
- Allow custom packages to define their own rules that you can add to your own server.

!!! note
Adding a `NameServer` to another requires `nserver>=3.0`

### Using Sub-Servers

```python
Expand Down Expand Up @@ -57,9 +53,6 @@ In particular errors will not propagate up from a child server to it's parent as

[`Blueprint`][nserver.server.Blueprint]s act as a container for rules. They are an efficient way to compose your application if you do not want or need to use functionality provided by a `QueryMiddleware` stack.

!!! note
Blueprints require `nserver>=3.0`

### Using Blueprints

```python
Expand Down Expand Up @@ -91,4 +84,4 @@ mysite.rules.insert(0, no_email_blueprint)
- Is used directly in `register_rule` (e.g. `some_server.register_rule(my_blueprint)`).
- If rule does not match an internal rule will continue to the next rule in the parent server.

In comparison the server classes will return `NXDOMAIN` if a rule doesn't match their internal rules.
In comparison `NameServer` instances will return `NXDOMAIN` if a rule doesn't match their internal rules.
12 changes: 7 additions & 5 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@ nav:
- error-handling.md
- subserver-blueprint.md
- production-deployment.md
- changelog.md
- external-resources.md
- changelog.md
- security.md
- contributing.md
- API Reference:
- ... | reference/nserver/*

Expand Down Expand Up @@ -84,10 +86,10 @@ plugins:
python:
paths:
- src
#import:
# - https://docs.python.org/3/objects.inv
# - https://mkdocstrings.github.io/objects.inv
# - https://mkdocstrings.github.io/griffe/objects.inv
import:
- https://docs.python.org/3/objects.inv
- https://mkdocstrings.github.io/objects.inv
- https://mkdocstrings.github.io/griffe/objects.inv
options:
filters:
- "!^_"
Expand Down
8 changes: 7 additions & 1 deletion src/nserver/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,13 @@ def prepare_middleware(self) -> None:
class NameServer(
MiddlewareMixin[m.QueryMiddleware, m.QueryExceptionHandlerMiddleware], RulesMixin, LoggingMixin
):
"""High level DNS Name Server for responding to DNS queries."""
"""High level DNS Name Server for responding to DNS queries.
*Changed in `3.0`*:
- "Raw" functionality removed and moved to `RawNameServer`.
- "Transport" and "Application" functionality removed.
"""

def __init__(self, name: str) -> None:
"""
Expand Down

0 comments on commit 0c41d3f

Please sign in to comment.